diff --git a/lerna.json b/lerna.json index 7f78b4d9f552..c6755da49f72 100644 --- a/lerna.json +++ b/lerna.json @@ -15,5 +15,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "16.3.0-canary.21" + "version": "16.3.0-canary.22" } \ No newline at end of file diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index 3712ed0e66fd..46d00e703055 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "16.3.0-canary.21", + "version": "16.3.0-canary.22", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index 0771fac1e8a4..9ccd1f8aa1ea 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "16.3.0-canary.21", + "version": "16.3.0-canary.22", "description": "ESLint configuration used by Next.js.", "license": "MIT", "repository": { @@ -12,7 +12,7 @@ "dist" ], "dependencies": { - "@next/eslint-plugin-next": "16.3.0-canary.21", + "@next/eslint-plugin-next": "16.3.0-canary.22", "eslint-import-resolver-node": "^0.3.6", "eslint-import-resolver-typescript": "^3.5.2", "eslint-plugin-import": "^2.32.0", diff --git a/packages/eslint-plugin-internal/package.json b/packages/eslint-plugin-internal/package.json index afd0f7d3578a..0336cd8ea173 100644 --- a/packages/eslint-plugin-internal/package.json +++ b/packages/eslint-plugin-internal/package.json @@ -1,7 +1,7 @@ { "name": "@next/eslint-plugin-internal", "private": true, - "version": "16.3.0-canary.21", + "version": "16.3.0-canary.22", "description": "ESLint plugin for working on Next.js.", "exports": { ".": "./src/eslint-plugin-internal.js" diff --git a/packages/eslint-plugin-next/package.json b/packages/eslint-plugin-next/package.json index c07e141660fe..0e3f7b1d930b 100644 --- a/packages/eslint-plugin-next/package.json +++ b/packages/eslint-plugin-next/package.json @@ -1,6 +1,6 @@ { "name": "@next/eslint-plugin-next", - "version": "16.3.0-canary.21", + "version": "16.3.0-canary.22", "description": "ESLint plugin for Next.js.", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/packages/font/package.json b/packages/font/package.json index ac338f605116..8ee570b81f90 100644 --- a/packages/font/package.json +++ b/packages/font/package.json @@ -1,7 +1,7 @@ { "name": "@next/font", "private": true, - "version": "16.3.0-canary.21", + "version": "16.3.0-canary.22", "repository": { "url": "vercel/next.js", "directory": "packages/font" diff --git a/packages/next-bundle-analyzer/package.json b/packages/next-bundle-analyzer/package.json index 6c9ed7a70593..ffe6d68bf8b3 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "16.3.0-canary.21", + "version": "16.3.0-canary.22", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index 244ea1ca16f9..cfcc5d8955d5 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "16.3.0-canary.21", + "version": "16.3.0-canary.22", "license": "MIT", "repository": { "type": "git", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index 365da878ca55..18a6ac84857b 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "16.3.0-canary.21", + "version": "16.3.0-canary.22", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index 45226be71a3f..be976813f679 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "16.3.0-canary.21", + "version": "16.3.0-canary.22", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-playwright/package.json b/packages/next-playwright/package.json index fb6af7915a0f..f7eac3b67864 100644 --- a/packages/next-playwright/package.json +++ b/packages/next-playwright/package.json @@ -1,6 +1,6 @@ { "name": "@next/playwright", - "version": "16.3.0-canary.21", + "version": "16.3.0-canary.22", "repository": { "url": "vercel/next.js", "directory": "packages/next-playwright" diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index d0a8a38fd9bd..7ea82ade1928 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "16.3.0-canary.21", + "version": "16.3.0-canary.22", "repository": { "url": "vercel/next.js", "directory": "packages/next-plugin-storybook" diff --git a/packages/next-polyfill-module/package.json b/packages/next-polyfill-module/package.json index 08f50c743633..df26cfe1284b 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "16.3.0-canary.21", + "version": "16.3.0-canary.22", "description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)", "main": "dist/polyfill-module.js", "license": "MIT", diff --git a/packages/next-polyfill-nomodule/package.json b/packages/next-polyfill-nomodule/package.json index a68c0877b3ea..68738c93b9fb 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "16.3.0-canary.21", + "version": "16.3.0-canary.22", "description": "A polyfill for non-dead, nomodule browsers.", "main": "dist/polyfill-nomodule.js", "license": "MIT", diff --git a/packages/next-routing/package.json b/packages/next-routing/package.json index 87a49883089e..9970aeb2fe5b 100644 --- a/packages/next-routing/package.json +++ b/packages/next-routing/package.json @@ -1,6 +1,6 @@ { "name": "@next/routing", - "version": "16.3.0-canary.21", + "version": "16.3.0-canary.22", "keywords": [ "react", "next", diff --git a/packages/next-rspack/package.json b/packages/next-rspack/package.json index a6fda7659fb4..703dcc46e67d 100644 --- a/packages/next-rspack/package.json +++ b/packages/next-rspack/package.json @@ -1,6 +1,6 @@ { "name": "next-rspack", - "version": "16.3.0-canary.21", + "version": "16.3.0-canary.22", "repository": { "url": "vercel/next.js", "directory": "packages/next-rspack" diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json index 7d17e9ff3893..1bbc9695726e 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "16.3.0-canary.21", + "version": "16.3.0-canary.22", "private": true, "files": [ "native/" diff --git a/packages/next/package.json b/packages/next/package.json index c6128bd70bce..6768fde1d11b 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "16.3.0-canary.21", + "version": "16.3.0-canary.22", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -101,7 +101,7 @@ ] }, "dependencies": { - "@next/env": "16.3.0-canary.21", + "@next/env": "16.3.0-canary.22", "@swc/helpers": "0.5.15", "baseline-browser-mapping": "^2.9.19", "caniuse-lite": "^1.0.30001579", @@ -165,11 +165,11 @@ "@modelcontextprotocol/sdk": "1.18.1", "@mswjs/interceptors": "0.23.0", "@napi-rs/triples": "1.2.0", - "@next/font": "16.3.0-canary.21", - "@next/polyfill-module": "16.3.0-canary.21", - "@next/polyfill-nomodule": "16.3.0-canary.21", - "@next/react-refresh-utils": "16.3.0-canary.21", - "@next/swc": "16.3.0-canary.21", + "@next/font": "16.3.0-canary.22", + "@next/polyfill-module": "16.3.0-canary.22", + "@next/polyfill-nomodule": "16.3.0-canary.22", + "@next/react-refresh-utils": "16.3.0-canary.22", + "@next/swc": "16.3.0-canary.22", "@opentelemetry/api": "1.6.0", "@playwright/test": "1.58.2", "@rspack/core": "1.6.7", diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index 2d98e45afc07..faf6bd0f656f 100644 --- a/packages/react-refresh-utils/package.json +++ b/packages/react-refresh-utils/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-refresh-utils", - "version": "16.3.0-canary.21", + "version": "16.3.0-canary.22", "description": "An experimental package providing utilities for React Refresh.", "repository": { "url": "vercel/next.js", diff --git a/packages/third-parties/package.json b/packages/third-parties/package.json index 26e57dc243ce..c15be6edca02 100644 --- a/packages/third-parties/package.json +++ b/packages/third-parties/package.json @@ -1,6 +1,6 @@ { "name": "@next/third-parties", - "version": "16.3.0-canary.21", + "version": "16.3.0-canary.22", "repository": { "url": "vercel/next.js", "directory": "packages/third-parties" @@ -27,7 +27,7 @@ "third-party-capital": "1.0.20" }, "devDependencies": { - "next": "16.3.0-canary.21", + "next": "16.3.0-canary.22", "outdent": "0.8.0", "prettier": "2.5.1", "typescript": "6.0.2" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6e3cf6aeb6a1..d2ee28ebc79c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -986,7 +986,7 @@ importers: packages/eslint-config-next: dependencies: '@next/eslint-plugin-next': - specifier: 16.3.0-canary.21 + specifier: 16.3.0-canary.22 version: link:../eslint-plugin-next eslint: specifier: '>=9.0.0' @@ -1063,7 +1063,7 @@ importers: packages/next: dependencies: '@next/env': - specifier: 16.3.0-canary.21 + specifier: 16.3.0-canary.22 version: link:../next-env '@swc/helpers': specifier: 0.5.15 @@ -1184,19 +1184,19 @@ importers: specifier: 1.2.0 version: 1.2.0 '@next/font': - specifier: 16.3.0-canary.21 + specifier: 16.3.0-canary.22 version: link:../font '@next/polyfill-module': - specifier: 16.3.0-canary.21 + specifier: 16.3.0-canary.22 version: link:../next-polyfill-module '@next/polyfill-nomodule': - specifier: 16.3.0-canary.21 + specifier: 16.3.0-canary.22 version: link:../next-polyfill-nomodule '@next/react-refresh-utils': - specifier: 16.3.0-canary.21 + specifier: 16.3.0-canary.22 version: link:../react-refresh-utils '@next/swc': - specifier: 16.3.0-canary.21 + specifier: 16.3.0-canary.22 version: link:../next-swc '@opentelemetry/api': specifier: 1.6.0 @@ -1930,7 +1930,7 @@ importers: version: 1.0.20 devDependencies: next: - specifier: 16.3.0-canary.21 + specifier: 16.3.0-canary.22 version: link:../next outdent: specifier: 0.8.0 diff --git a/turbopack/crates/turbo-tasks-backend/src/backend/mod.rs b/turbopack/crates/turbo-tasks-backend/src/backend/mod.rs index b940c7d4f418..c7f547215bcc 100644 --- a/turbopack/crates/turbo-tasks-backend/src/backend/mod.rs +++ b/turbopack/crates/turbo-tasks-backend/src/backend/mod.rs @@ -758,7 +758,7 @@ impl TurboTasksBackendInner { // done: true } it must have Output and would early return. let old = task.set_in_progress(in_progress_state); debug_assert!(old.is_none(), "InProgress already exists"); - ctx.schedule_task(task, TaskPriority::Initial); + ctx.schedule_task(task, TaskPriority::Recomputation); Ok(Err(listener)) } @@ -896,7 +896,7 @@ impl TurboTasksBackendInner { TaskExecutionReason::CellNotAvailable, EventDescription::new(|| task.get_task_desc_fn()), ); - ctx.schedule_task(task, TaskPriority::Initial); + ctx.schedule_task(task, TaskPriority::Recomputation); Ok(Err(listener)) } diff --git a/turbopack/crates/turbo-tasks-backend/src/backend/operation/invalidate.rs b/turbopack/crates/turbo-tasks-backend/src/backend/operation/invalidate.rs index e3ce46ea19a2..6b19f1dea005 100644 --- a/turbopack/crates/turbo-tasks-backend/src/backend/operation/invalidate.rs +++ b/turbopack/crates/turbo-tasks-backend/src/backend/operation/invalidate.rs @@ -1,6 +1,6 @@ use bincode::{Decode, Encode}; use smallvec::SmallVec; -use turbo_tasks::{TaskExecutionReason, TaskId, event::EventDescription}; +use turbo_tasks::{TaskExecutionReason, TaskId, TaskPriority, event::EventDescription}; use crate::{ backend::{ @@ -224,6 +224,16 @@ pub fn make_task_dirty_internal( *stale = true; } let current = task.get_dirty(); + let parent_priority = ctx.get_current_task_priority(); + let parent_priority = if matches!(parent_priority, TaskPriority::Recomputation) { + // When an invalidation was triggered during recomputation (or an initial execution that was + // triggered from recomputation), we do not want to treat that as recomputation. + // That would make recomputation to be very viral, and breaks ordering. So we reset + // execution order to initial. + TaskPriority::Initial + } else { + parent_priority + }; let (old_self_dirty, old_current_session_self_clean, parent_priority) = match current { Some(Dirtyness::Dirty(current_priority)) => { #[cfg(feature = "trace_task_dirty")] @@ -235,15 +245,15 @@ pub fn make_task_dirty_internal( ) .entered(); // already dirty - let parent_priority = ctx.get_current_task_priority(); - if *current_priority >= parent_priority { + if matches!(*current_priority, TaskPriority::Initial) + || *current_priority > parent_priority + { // Update the priority to be the lower one task.set_dirty(Dirtyness::Dirty(parent_priority)); } return; } Some(Dirtyness::SessionDependent) => { - let parent_priority = ctx.get_current_task_priority(); task.set_dirty(Dirtyness::Dirty(parent_priority)); // It was a session-dependent dirty before, so we need to remove that clean count let was_current_session_clean = task.current_session_clean(); @@ -265,7 +275,6 @@ pub fn make_task_dirty_internal( } } None => { - let parent_priority = ctx.get_current_task_priority(); task.set_dirty(Dirtyness::Dirty(parent_priority)); // It was clean before, so we need to increase the dirty count (false, false, parent_priority) diff --git a/turbopack/crates/turbo-tasks/src/manager.rs b/turbopack/crates/turbo-tasks/src/manager.rs index 39564f1926cf..70b1f7c4b760 100644 --- a/turbopack/crates/turbo-tasks/src/manager.rs +++ b/turbopack/crates/turbo-tasks/src/manager.rs @@ -410,6 +410,7 @@ pub enum TaskPriority { Invalidation { priority: Reverse, }, + Recomputation, } impl TaskPriority { @@ -445,6 +446,7 @@ impl TaskPriority { *self } } + TaskPriority::Recomputation => TaskPriority::Recomputation, } } } @@ -454,6 +456,7 @@ impl Display for TaskPriority { match self { TaskPriority::Initial => write!(f, "initial"), TaskPriority::Invalidation { priority } => write!(f, "invalidation({})", priority.0), + TaskPriority::Recomputation => write!(f, "recomputation"), } } } diff --git a/turbopack/crates/turbo-tasks/src/task_execution_reason.rs b/turbopack/crates/turbo-tasks/src/task_execution_reason.rs index ffab24d2fcb7..74418c9c4af0 100644 --- a/turbopack/crates/turbo-tasks/src/task_execution_reason.rs +++ b/turbopack/crates/turbo-tasks/src/task_execution_reason.rs @@ -1,13 +1,28 @@ #[derive(Debug)] pub enum TaskExecutionReason { + /// A root task was initially scheduled and is executed Initial, - Local, + /// A task output was read, but the output is not available, so the task was scheduled and + /// executed to produce the output OutputNotAvailable, + /// A task cell was read, but the cell content is not available, so the task was scheduled and + /// executed to produce the cell content CellNotAvailable, + /// A task was marked as dirty and is active on it's own (maybe root or currently awaited), so + /// it was scheduled and executed to update the task output Invalidated, + /// A dirty task has been activated, so it was scheduled and executed to update the task output ActivateDirty, + /// A task has been activated for the first time (no output yet), so it was scheduled and + /// executed to produce the task output ActivateInitial, + /// A task was connected as child in `active_tracking == false` mode for the first time (no + /// output yet), so it was scheduled and executed to produce the task output. + /// Or a task was called inside of a turbo_tasks::run closure for the first time (no output + /// yet), so it was scheduled and executed to produce the task output. Connect, + /// An in-progress task was marked as stale, so it was scheduled again after execution and is + /// executing again to update the task output. Stale, } @@ -15,7 +30,6 @@ impl TaskExecutionReason { pub fn as_str(&self) -> &'static str { match self { TaskExecutionReason::Initial => "initial", - TaskExecutionReason::Local => "local", TaskExecutionReason::OutputNotAvailable => "output_not_available", TaskExecutionReason::CellNotAvailable => "cell_not_available", TaskExecutionReason::Invalidated => "invalidated",