diff --git a/Cargo.lock b/Cargo.lock index dfabf8ac4203e7..8cfaeed73fdab1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -328,19 +328,6 @@ dependencies = [ "syn 2.0.104", ] -[[package]] -name = "async-compression" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942c7cd7ae39e91bde4820d74132e9862e62c2f386c3aa90ccf55949f5bad63a" -dependencies = [ - "flate2", - "futures-core", - "memchr", - "pin-project-lite", - "tokio", -] - [[package]] name = "async-stream" version = "0.3.4" @@ -572,6 +559,24 @@ dependencies = [ "serde", ] +[[package]] +name = "bincode" +version = "2.0.1" +source = "git+https://github.com/bgw/bincode.git?branch=bgw%2Fpatches#19f09c5f6895d769883c10b3d374f761ab7fe83d" +dependencies = [ + "bincode_derive", + "serde", + "unty", +] + +[[package]] +name = "bincode_derive" +version = "2.0.1" +source = "git+https://github.com/bgw/bincode.git?branch=bgw%2Fpatches#19f09c5f6895d769883c10b3d374f761ab7fe83d" +dependencies = [ + "virtue", +] + [[package]] name = "bindgen" version = "0.70.1" @@ -1178,7 +1183,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35584c5fcba8059780748866387fb97c5a203bcfc563fc3d0790af406727a117" dependencies = [ "anyhow", - "bincode", + "bincode 1.3.3", "colored", "glob", "libc", @@ -6753,9 +6758,9 @@ checksum = "03b634d87b960ab1a38c4fe143b508576f075e7c978bfad18217645ebfdfa2ec" [[package]] name = "smallvec" -version = "1.13.1" +version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" dependencies = [ "serde", ] @@ -9079,6 +9084,20 @@ dependencies = [ "utf-8", ] +[[package]] +name = "turbo-bincode" +version = "0.0.0" +dependencies = [ + "bincode 2.0.1", + "either", + "indexmap 2.9.0", + "mime", + "ringmap", + "serde", + "serde_json", + "smallvec", +] + [[package]] name = "turbo-dyn-eq-hash" version = "0.0.1" @@ -9151,7 +9170,7 @@ dependencies = [ name = "turbo-static" version = "0.1.0" dependencies = [ - "bincode", + "bincode 1.3.3", "clap", "ctrlc", "ignore", @@ -9662,8 +9681,8 @@ name = "turbopack-dev-server" version = "0.1.0" dependencies = [ "anyhow", - "async-compression", "auto-hash-map", + "flate2", "futures", "hyper 0.14.32", "hyper-tungstenite", @@ -10237,6 +10256,12 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" +[[package]] +name = "unty" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d49784317cd0d1ee7ec5c716dd598ec5b4483ea832a2dced265471cc0f690ae" + [[package]] name = "url" version = "2.5.4" @@ -10419,7 +10444,7 @@ dependencies = [ "anyhow", "async-trait", "base64 0.22.1", - "bincode", + "bincode 1.3.3", "bytecheck 0.6.11", "bytes", "derive_more 2.0.1", @@ -10436,6 +10461,12 @@ dependencies = [ "virtual-mio", ] +[[package]] +name = "virtue" +version = "0.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "051eb1abcf10076295e815102942cc58f9d5e3b4560e46e53c21e8ff6f3af7b1" + [[package]] name = "vlq" version = "0.5.1" @@ -10806,7 +10837,7 @@ dependencies = [ "anyhow", "async-trait", "base64 0.22.1", - "bincode", + "bincode 1.3.3", "bytecheck 0.6.11", "bytes", "derive_more 2.0.1", @@ -10912,7 +10943,7 @@ dependencies = [ "anyhow", "async-trait", "base64 0.22.1", - "bincode", + "bincode 1.3.3", "blake3", "bus", "bytecheck 0.6.11", diff --git a/Cargo.toml b/Cargo.toml index 84f520685ad341..aa08933e9e5d7d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -293,6 +293,7 @@ next-taskless = { path = "crates/next-taskless" } # Turbopack auto-hash-map = { path = "turbopack/crates/turbo-tasks-auto-hash-map" } +turbo-bincode = { path = "turbopack/crates/turbo-bincode" } turbo-prehash = { path = "turbopack/crates/turbo-prehash" } turbo-rcstr = { path = "turbopack/crates/turbo-rcstr" } turbo-dyn-eq-hash = { path = "turbopack/crates/turbo-dyn-eq-hash" } @@ -359,6 +360,7 @@ preset_env_base = "6.0.0" # General Deps +bincode = { version = "2.0.1", features = ["serde"] } chromiumoxide = { version = "0.5.4", features = [ "tokio-runtime", ], default-features = false } @@ -371,10 +373,6 @@ allsorts = { version = "0.14.0", default-features = false, features = [ "flate2_rust", ] } anyhow = "1.0.100" -async-compression = { version = "0.3.13", default-features = false, features = [ - "gzip", - "tokio", -] } async-trait = "0.1.64" bitfield = "0.18.0" byteorder = "1.5.0" @@ -481,4 +479,5 @@ webbrowser = "1.0.6" inventory = "0.3.21" [patch.crates-io] +bincode = { git = "https://github.com/bgw/bincode.git", branch = "bgw/patches" } mdxjs = { git = "https://github.com/mischnic/mdxjs-rs.git", branch = "swc-core-32" } diff --git a/apps/bundle-analyzer/package.json b/apps/bundle-analyzer/package.json index 1a6b1e675d08b9..db5a679907771c 100644 --- a/apps/bundle-analyzer/package.json +++ b/apps/bundle-analyzer/package.json @@ -18,7 +18,7 @@ "clsx": "^2.1.1", "cmdk": "1.0.4", "lucide-react": "^0.554.0", - "next": "16.0.1", + "next": "16.0.7", "next-themes": "^0.4.6", "polished": "^4.3.1", "react": "19.2.0", diff --git a/apps/docs/package.json b/apps/docs/package.json index a93df5d7f18cdf..b46a5bd5c87c07 100644 --- a/apps/docs/package.json +++ b/apps/docs/package.json @@ -12,7 +12,7 @@ "fumadocs-core": "15.7.12", "fumadocs-mdx": "11.10.0", "fumadocs-ui": "15.7.12", - "next": "15.5.3", + "next": "15.5.7", "react": "19.1.1", "react-dom": "19.1.1" }, diff --git a/docs/01-app/01-getting-started/17-deploying.mdx b/docs/01-app/01-getting-started/17-deploying.mdx index e0f65d31ca8b86..cf6f7b88a9bd51 100644 --- a/docs/01-app/01-getting-started/17-deploying.mdx +++ b/docs/01-app/01-getting-started/17-deploying.mdx @@ -76,6 +76,7 @@ Refer to each provider's documentation for information on supported Next.js feat - [AWS Amplify Hosting](https://docs.amplify.aws/nextjs/start/quickstart/nextjs-app-router-client-components) - [Cloudflare](https://developers.cloudflare.com/workers/frameworks/framework-guides/nextjs) - [Deno Deploy](https://docs.deno.com/examples/next_tutorial) +- [Firebase App Hosting](https://firebase.google.com/docs/app-hosting/get-started) - [Netlify](https://docs.netlify.com/frameworks/next-js/overview/#next-js-support-on-netlify) - [Vercel](https://vercel.com/docs/frameworks/nextjs) diff --git a/docs/01-app/02-guides/data-security.mdx b/docs/01-app/02-guides/data-security.mdx index db656cf0e31526..2c12d4354a4dc9 100644 --- a/docs/01-app/02-guides/data-security.mdx +++ b/docs/01-app/02-guides/data-security.mdx @@ -397,14 +397,12 @@ However, for this to happen, the captured variables are sent to the client and b ### Overwriting encryption keys (advanced) -When self-hosting your Next.js application across multiple servers, each server instance may end up with a different encryption key, leading to potential inconsistencies. +When **self-hosting** your Next.js application across multiple servers, each server instance may end up with a different encryption key, leading to potential inconsistencies. To mitigate this, you can overwrite the encryption key using the `process.env.NEXT_SERVER_ACTIONS_ENCRYPTION_KEY` environment variable. Specifying this variable ensures that your encryption keys are persistent across builds, and all server instances use the same key. This variable **must** be AES-GCM encrypted. This is an advanced use case where consistent encryption behavior across multiple deployments is critical for your application. You should consider standard security practices such key rotation and signing. -> **Good to know:** Next.js applications deployed to Vercel automatically handle this. - ### Allowed origins (advanced) Since Server Actions can be invoked in a `
` element, this opens them up to [CSRF attacks](https://developer.mozilla.org/en-US/docs/Glossary/CSRF). diff --git a/packages/next/src/next-devtools/dev-overlay/components/errors/dev-tools-indicator/draggable.tsx b/packages/next/src/next-devtools/dev-overlay/components/errors/dev-tools-indicator/draggable.tsx index 446a50063f9af0..93a9e04681e748 100644 --- a/packages/next/src/next-devtools/dev-overlay/components/errors/dev-tools-indicator/draggable.tsx +++ b/packages/next/src/next-devtools/dev-overlay/components/errors/dev-tools-indicator/draggable.tsx @@ -143,17 +143,7 @@ export function Draggable({ } return ( -
+
{children}
) @@ -208,6 +198,7 @@ function useDrag(options: UseDragOptions) { velocities.current = [] ref.current?.classList.remove('dev-tools-grabbing') + ref.current?.style.removeProperty('-webkit-user-select') document.body.style.removeProperty('user-select') document.body.style.removeProperty('-webkit-user-select') }, []) @@ -310,6 +301,7 @@ function useDrag(options: UseDragOptions) { machine.current = { state: 'drag', pointerId: e.pointerId } ref.current?.setPointerCapture(e.pointerId) ref.current?.classList.add('dev-tools-grabbing') + ref.current?.style.setProperty('-webkit-user-select', 'none') document.body.style.userSelect = 'none' document.body.style.webkitUserSelect = 'none' options.onDragStart?.() diff --git a/packages/next/src/next-devtools/dev-overlay/components/overview/segment-explorer.css b/packages/next/src/next-devtools/dev-overlay/components/overview/segment-explorer.css index 2505a8c9068293..26fc22d638efd2 100644 --- a/packages/next/src/next-devtools/dev-overlay/components/overview/segment-explorer.css +++ b/packages/next/src/next-devtools/dev-overlay/components/overview/segment-explorer.css @@ -41,7 +41,6 @@ display: flex; align-items: center; white-space: pre; - cursor: default; color: var(--color-gray-1000); } @@ -90,8 +89,6 @@ line-height: 16px; font-size: var(--size-12); font-weight: 500; - user-select: none; - cursor: pointer; background-color: var(--color-gray-300); color: var(--color-gray-1000); } diff --git a/packages/next/src/server/app-render/action-handler.ts b/packages/next/src/server/app-render/action-handler.ts index 3283d261eccdda..bb7f2cc4ecf002 100644 --- a/packages/next/src/server/app-render/action-handler.ts +++ b/packages/next/src/server/app-render/action-handler.ts @@ -49,7 +49,10 @@ import { warn } from '../../build/output/log' import { RequestCookies, ResponseCookies } from '../web/spec-extension/cookies' import { HeadersAdapter } from '../web/spec-extension/adapters/headers' import { fromNodeOutgoingHttpHeaders } from '../web/utils' -import { selectWorkerForForwarding, type ServerModuleMap } from './action-utils' +import { + selectWorkerForForwarding, + type ServerModuleMap, +} from './manifests-singleton' import { isNodeNextRequest, isWebNextRequest } from '../base-http/helpers' import { RedirectStatusCode } from '../../client/components/redirect-status-code' import { synchronizeMutableCookies } from '../async-storage/request-store' diff --git a/packages/next/src/server/app-render/action-utils.ts b/packages/next/src/server/app-render/action-utils.ts deleted file mode 100644 index 422286764c97fe..00000000000000 --- a/packages/next/src/server/app-render/action-utils.ts +++ /dev/null @@ -1,111 +0,0 @@ -import type { ActionManifest } from '../../build/webpack/plugins/flight-client-entry-plugin' -import { normalizeAppPath } from '../../shared/lib/router/utils/app-paths' -import { pathHasPrefix } from '../../shared/lib/router/utils/path-has-prefix' -import { removePathPrefix } from '../../shared/lib/router/utils/remove-path-prefix' -import { getServerActionsManifest } from './manifests-singleton' -import { workAsyncStorage } from './work-async-storage.external' - -export interface ServerModuleMap { - readonly [name: string]: { - readonly id: string | number - readonly name: string - readonly chunks: Readonly> // currently not used - readonly async?: boolean - } -} - -// This function creates a Flight-acceptable server module map proxy from our -// Server Reference Manifest similar to our client module map. -// This is because our manifest contains a lot of internal Next.js data that -// are relevant to the runtime, workers, etc. that React doesn't need to know. -export function createServerModuleMap({ - serverActionsManifest, -}: { - serverActionsManifest: ActionManifest -}): ServerModuleMap { - return new Proxy( - {}, - { - get: (_, id: string) => { - const workers = - serverActionsManifest[ - process.env.NEXT_RUNTIME === 'edge' ? 'edge' : 'node' - ]?.[id]?.workers - - if (!workers) { - return undefined - } - - const workStore = workAsyncStorage.getStore() - - let workerEntry: - | { moduleId: string | number; async: boolean } - | undefined - - if (workStore) { - workerEntry = workers[normalizeWorkerPageName(workStore.page)] - } else { - // If there's no work store defined, we can assume that a server - // module map is needed during module evaluation, e.g. to create a - // server action using a higher-order function. Therefore it should be - // safe to return any entry from the manifest that matches the action - // ID. They all refer to the same module ID, which must also exist in - // the current page bundle. TODO: This is currently not guaranteed in - // Turbopack, and needs to be fixed. - workerEntry = Object.values(workers).at(0) - } - - if (!workerEntry) { - return undefined - } - - const { moduleId, async } = workerEntry - - return { id: moduleId, name: id, chunks: [], async } - }, - } - ) -} - -/** - * Checks if the requested action has a worker for the current page. - * If not, it returns the first worker that has a handler for the action. - */ -export function selectWorkerForForwarding(actionId: string, pageName: string) { - const serverActionsManifest = getServerActionsManifest() - const workers = - serverActionsManifest[ - process.env.NEXT_RUNTIME === 'edge' ? 'edge' : 'node' - ][actionId]?.workers - const workerName = normalizeWorkerPageName(pageName) - - // no workers, nothing to forward to - if (!workers) return - - // if there is a worker for this page, no need to forward it. - if (workers[workerName]) { - return - } - - // otherwise, grab the first worker that has a handler for this action id - return denormalizeWorkerPageName(Object.keys(workers)[0]) -} - -/** - * The flight entry loader keys actions by bundlePath. - * bundlePath corresponds with the relative path (including 'app') to the page entrypoint. - */ -function normalizeWorkerPageName(pageName: string) { - if (pathHasPrefix(pageName, 'app')) { - return pageName - } - - return 'app' + pageName -} - -/** - * Converts a bundlePath (relative path to the entrypoint) to a routable page name - */ -function denormalizeWorkerPageName(bundlePath: string) { - return normalizeAppPath(removePathPrefix(bundlePath, 'app')) -} diff --git a/packages/next/src/server/app-render/manifests-singleton.ts b/packages/next/src/server/app-render/manifests-singleton.ts index 7cf3fc467cd70e..c917feefc6e9bd 100644 --- a/packages/next/src/server/app-render/manifests-singleton.ts +++ b/packages/next/src/server/app-render/manifests-singleton.ts @@ -3,9 +3,19 @@ import type { ClientReferenceManifest } from '../../build/webpack/plugins/flight import type { DeepReadonly } from '../../shared/lib/deep-readonly' import { InvariantError } from '../../shared/lib/invariant-error' import { normalizeAppPath } from '../../shared/lib/router/utils/app-paths' -import { createServerModuleMap, type ServerModuleMap } from './action-utils' +import { pathHasPrefix } from '../../shared/lib/router/utils/path-has-prefix' +import { removePathPrefix } from '../../shared/lib/router/utils/remove-path-prefix' import { workAsyncStorage } from './work-async-storage.external' +export interface ServerModuleMap { + readonly [name: string]: { + readonly id: string | number + readonly name: string + readonly chunks: Readonly> // currently not used + readonly async?: boolean + } +} + // This is a global singleton that is, among other things, also used to // encode/decode bound args of server function closures. This can't be using a // AsyncLocalStorage as it might happen at the module level. @@ -162,6 +172,105 @@ function createProxiedClientReferenceManifest( ) as DeepReadonly } +/** + * This function creates a Flight-acceptable server module map proxy from our + * Server Reference Manifest similar to our client module map. This is because + * our manifest contains a lot of internal Next.js data that are relevant to the + * runtime, workers, etc. that React doesn't need to know. + */ +function createServerModuleMap(): ServerModuleMap { + return new Proxy( + {}, + { + get: (_, id: string) => { + const workers = + getServerActionsManifest()[ + process.env.NEXT_RUNTIME === 'edge' ? 'edge' : 'node' + ]?.[id]?.workers + + if (!workers) { + return undefined + } + + const workStore = workAsyncStorage.getStore() + + let workerEntry: + | { moduleId: string | number; async: boolean } + | undefined + + if (workStore) { + workerEntry = workers[normalizeWorkerPageName(workStore.page)] + } else { + // If there's no work store defined, we can assume that a server + // module map is needed during module evaluation, e.g. to create a + // server action using a higher-order function. Therefore it should be + // safe to return any entry from the manifest that matches the action + // ID. They all refer to the same module ID, which must also exist in + // the current page bundle. TODO: This is currently not guaranteed in + // Turbopack, and needs to be fixed. + workerEntry = Object.values(workers).at(0) + } + + if (!workerEntry) { + return undefined + } + + const { moduleId, async } = workerEntry + + return { id: moduleId, name: id, chunks: [], async } + }, + } + ) +} + +/** + * The flight entry loader keys actions by bundlePath. bundlePath corresponds + * with the relative path (including 'app') to the page entrypoint. + */ +function normalizeWorkerPageName(pageName: string) { + if (pathHasPrefix(pageName, 'app')) { + return pageName + } + + return 'app' + pageName +} + +/** + * Converts a bundlePath (relative path to the entrypoint) to a routable page + * name. + */ +function denormalizeWorkerPageName(bundlePath: string) { + return normalizeAppPath(removePathPrefix(bundlePath, 'app')) +} + +/** + * Checks if the requested action has a worker for the current page. + * If not, it returns the first worker that has a handler for the action. + */ +export function selectWorkerForForwarding( + actionId: string, + pageName: string +): string | undefined { + const serverActionsManifest = getServerActionsManifest() + const workers = + serverActionsManifest[ + process.env.NEXT_RUNTIME === 'edge' ? 'edge' : 'node' + ][actionId]?.workers + + // There are no workers to handle this action, nothing to forward to. + if (!workers) { + return + } + + // If there is an entry for the current page, we don't need to forward. + if (workers[normalizeWorkerPageName(pageName)]) { + return + } + + // Otherwise, grab the first worker that has a handler for this action id. + return denormalizeWorkerPageName(Object.keys(workers)[0]) +} + export function setManifestsSingleton({ page, clientReferenceManifest, @@ -180,10 +289,6 @@ export function setManifestsSingleton({ ) existingSingleton.serverActionsManifest = serverActionsManifest - - existingSingleton.serverModuleMap = createServerModuleMap({ - serverActionsManifest, - }) } else { const clientReferenceManifestsPerRoute = new Map< string, @@ -194,15 +299,11 @@ export function setManifestsSingleton({ clientReferenceManifestsPerRoute ) - const serverModuleMap = createServerModuleMap({ - serverActionsManifest, - }) - globalThisWithManifests[MANIFESTS_SINGLETON] = { clientReferenceManifestsPerRoute, proxiedClientReferenceManifest, serverActionsManifest, - serverModuleMap, + serverModuleMap: createServerModuleMap(), } } } diff --git a/packages/next/src/shared/lib/get-img-props.ts b/packages/next/src/shared/lib/get-img-props.ts index 50073562aa20b2..e821edca2428c2 100644 --- a/packages/next/src/shared/lib/get-img-props.ts +++ b/packages/next/src/shared/lib/get-img-props.ts @@ -1,4 +1,5 @@ import { warnOnce } from './utils/warn-once' +import { getDeploymentId } from './deployment-id' import { getImageBlurSvg } from './image-blur-svg' import { imageConfigDefault } from './image-config' import type { @@ -230,6 +231,11 @@ function generateImgAttrs({ loader, }: GenImgAttrsData): GenImgAttrsResult { if (unoptimized) { + const deploymentId = getDeploymentId() + if (src.startsWith('/') && deploymentId) { + const sep = src.includes('?') ? '&' : '?' + src = `${src}${sep}dpl=${deploymentId}` + } return { src, srcSet: undefined, sizes: undefined } } diff --git a/packages/next/src/shared/lib/image-loader.ts b/packages/next/src/shared/lib/image-loader.ts index 16041bc50c8746..7731934c685de1 100644 --- a/packages/next/src/shared/lib/image-loader.ts +++ b/packages/next/src/shared/lib/image-loader.ts @@ -97,9 +97,7 @@ function defaultLoader({ let deploymentId = getDeploymentId() return `${config.path}?url=${encodeURIComponent(src)}&w=${width}&q=${q}${ - src.startsWith('/_next/static/media/') && deploymentId - ? `&dpl=${deploymentId}` - : '' + src.startsWith('/') && deploymentId ? `&dpl=${deploymentId}` : '' }` } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index acae846720f0cf..526236699dd638 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -158,7 +158,7 @@ importers: version: 1.1.0 '@testing-library/jest-dom': specifier: 6.1.2 - version: 6.1.2(@jest/globals@29.7.0)(@types/jest@29.5.5)(jest@29.7.0(@types/node@20.17.6(patch_hash=rvl3vkomen3tospgr67bzubfyu))(babel-plugin-macros@3.1.0))(vitest@3.0.4(@types/node@20.17.6(patch_hash=rvl3vkomen3tospgr67bzubfyu))(jiti@2.5.1)(sass@1.54.0)(tsx@4.19.2)) + version: 6.1.2(@jest/globals@29.7.0)(@types/jest@29.5.5)(jest@29.7.0(@types/node@20.17.6(patch_hash=rvl3vkomen3tospgr67bzubfyu))(babel-plugin-macros@3.1.0)) '@testing-library/react': specifier: ^15.0.5 version: 15.0.7(@types/react@19.2.2)(react-dom@19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203))(react@19.3.0-canary-7dc903cd-20251203) @@ -646,8 +646,8 @@ importers: specifier: ^0.554.0 version: 0.554.0(react@19.3.0-canary-7dc903cd-20251203) next: - specifier: 16.0.1 - version: 16.0.1(@babel/core@7.26.10)(@opentelemetry/api@1.6.0)(@playwright/test@1.51.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@0.0.0-experimental-3fde738-20250918)(react-dom@19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203))(react@19.3.0-canary-7dc903cd-20251203)(sass@1.77.8) + specifier: 16.0.7 + version: 16.0.7(@babel/core@7.26.10)(@opentelemetry/api@1.6.0)(@playwright/test@1.51.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@0.0.0-experimental-3fde738-20250918)(react-dom@19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203))(react@19.3.0-canary-7dc903cd-20251203)(sass@1.77.8) next-themes: specifier: ^0.4.6 version: 0.4.6(react-dom@19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203))(react@19.3.0-canary-7dc903cd-20251203) @@ -705,16 +705,16 @@ importers: dependencies: fumadocs-core: specifier: 15.7.12 - version: 15.7.12(@types/react@19.2.2)(next@15.5.3(@babel/core@7.26.10)(@opentelemetry/api@1.6.0)(@playwright/test@1.51.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@0.0.0-experimental-3fde738-20250918)(react-dom@19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203))(react@19.3.0-canary-7dc903cd-20251203)(sass@1.77.8))(react-dom@19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203))(react@19.3.0-canary-7dc903cd-20251203) + version: 15.7.12(@types/react@19.2.2)(next@15.5.7(@babel/core@7.26.10)(@opentelemetry/api@1.6.0)(@playwright/test@1.51.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@0.0.0-experimental-3fde738-20250918)(react-dom@19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203))(react@19.3.0-canary-7dc903cd-20251203)(sass@1.77.8))(react-dom@19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203))(react@19.3.0-canary-7dc903cd-20251203) fumadocs-mdx: specifier: 11.10.0 - version: 11.10.0(fumadocs-core@15.7.12(@types/react@19.2.2)(next@15.5.3(@babel/core@7.26.10)(@opentelemetry/api@1.6.0)(@playwright/test@1.51.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@0.0.0-experimental-3fde738-20250918)(react-dom@19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203))(react@19.3.0-canary-7dc903cd-20251203)(sass@1.77.8))(react-dom@19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203))(react@19.3.0-canary-7dc903cd-20251203))(next@15.5.3(@babel/core@7.26.10)(@opentelemetry/api@1.6.0)(@playwright/test@1.51.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@0.0.0-experimental-3fde738-20250918)(react-dom@19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203))(react@19.3.0-canary-7dc903cd-20251203)(sass@1.77.8))(react@19.3.0-canary-7dc903cd-20251203)(vite@6.2.5(@types/node@20.17.6(patch_hash=rvl3vkomen3tospgr67bzubfyu))(jiti@2.5.1)(sass@1.77.8)(tsx@4.19.2)) + version: 11.10.0(fumadocs-core@15.7.12(@types/react@19.2.2)(next@15.5.7(@babel/core@7.26.10)(@opentelemetry/api@1.6.0)(@playwright/test@1.51.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@0.0.0-experimental-3fde738-20250918)(react-dom@19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203))(react@19.3.0-canary-7dc903cd-20251203)(sass@1.77.8))(react-dom@19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203))(react@19.3.0-canary-7dc903cd-20251203))(next@15.5.7(@babel/core@7.26.10)(@opentelemetry/api@1.6.0)(@playwright/test@1.51.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@0.0.0-experimental-3fde738-20250918)(react-dom@19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203))(react@19.3.0-canary-7dc903cd-20251203)(sass@1.77.8))(react@19.3.0-canary-7dc903cd-20251203) fumadocs-ui: specifier: 15.7.12 - version: 15.7.12(@types/react-dom@19.2.1(@types/react@19.2.2))(@types/react@19.2.2)(next@15.5.3(@babel/core@7.26.10)(@opentelemetry/api@1.6.0)(@playwright/test@1.51.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@0.0.0-experimental-3fde738-20250918)(react-dom@19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203))(react@19.3.0-canary-7dc903cd-20251203)(sass@1.77.8))(react-dom@19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203))(react@19.3.0-canary-7dc903cd-20251203)(tailwindcss@4.1.13) + version: 15.7.12(@types/react-dom@19.2.1(@types/react@19.2.2))(@types/react@19.2.2)(next@15.5.7(@babel/core@7.26.10)(@opentelemetry/api@1.6.0)(@playwright/test@1.51.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@0.0.0-experimental-3fde738-20250918)(react-dom@19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203))(react@19.3.0-canary-7dc903cd-20251203)(sass@1.77.8))(react-dom@19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203))(react@19.3.0-canary-7dc903cd-20251203)(tailwindcss@4.1.13) next: - specifier: 15.5.3 - version: 15.5.3(@babel/core@7.26.10)(@opentelemetry/api@1.6.0)(@playwright/test@1.51.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@0.0.0-experimental-3fde738-20250918)(react-dom@19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203))(react@19.3.0-canary-7dc903cd-20251203)(sass@1.77.8) + specifier: 15.5.7 + version: 15.5.7(@babel/core@7.26.10)(@opentelemetry/api@1.6.0)(@playwright/test@1.51.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@0.0.0-experimental-3fde738-20250918)(react-dom@19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203))(react@19.3.0-canary-7dc903cd-20251203)(sass@1.77.8) react: specifier: 19.3.0-canary-7dc903cd-20251203 version: 19.3.0-canary-7dc903cd-20251203 @@ -745,7 +745,7 @@ importers: version: 9.37.0(jiti@2.5.1) eslint-config-next: specifier: canary - version: 16.1.0-canary.6(eslint-plugin-import-x@4.3.1(eslint@9.37.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.37.0(jiti@2.5.1))(typescript@5.9.2) + version: link:../../packages/eslint-config-next tailwindcss: specifier: 4.1.13 version: 4.1.13 @@ -2061,9 +2061,6 @@ packages: '@actions/http-client@2.2.0': resolution: {integrity: sha512-q+epW0trjVUUHboliPb4UF9g2msf+w61b32tAkFEwL/IwP0DQWgbCMM0Hbe3e3WXSKz5VcUXbzJQgy8Hkra/Lg==} - '@adobe/css-tools@4.3.1': - resolution: {integrity: sha512-/62yikz7NLScCGAAST5SHdnjaDJQBDq0M2muyRTpf2VQhw6StBg2ALiu73zSJQ4fMVLA+0uBhBHAle7Wg+2kSg==} - '@adobe/css-tools@4.4.1': resolution: {integrity: sha512-12WGKBQzjUAI4ayyF4IAtfw2QR/IDoqk6jTddXDhtYTJF9ASmoE1zst7cVtP0aL/F1jUJL5r+JxKXKEgHNbEUQ==} @@ -4377,14 +4374,11 @@ packages: '@napi-rs/wasm-runtime@1.0.7': resolution: {integrity: sha512-SeDnOO0Tk7Okiq6DbXmmBODgOAb9dp9gjlphokTUxmt8U3liIP1ZsozBahH69j/RJv+Rfs6IwUKHTgQYJ/HBAw==} - '@next/env@15.5.3': - resolution: {integrity: sha512-RSEDTRqyihYXygx/OJXwvVupfr9m04+0vH8vyy0HfZ7keRto6VX9BbEk0J2PUk0VGy6YhklJUSrgForov5F9pw==} - - '@next/env@16.0.1': - resolution: {integrity: sha512-LFvlK0TG2L3fEOX77OC35KowL8D7DlFF45C0OvKMC4hy8c/md1RC4UMNDlUGJqfCoCS2VWrZ4dSE6OjaX5+8mw==} + '@next/env@15.5.7': + resolution: {integrity: sha512-4h6Y2NyEkIEN7Z8YxkA27pq6zTkS09bUSYC0xjd0NpwFxjnIKeZEeH591o5WECSmjpUhLn3H2QLJcDye3Uzcvg==} - '@next/eslint-plugin-next@16.1.0-canary.6': - resolution: {integrity: sha512-KzlJwpe1UJCZBfJ/Ce2aMfWPfyqsC63rMFsHlvUWzlOp2+x8vyYCB1/fa4wWdiSyoR39pOn1mSVsgZpYUL2Aug==} + '@next/env@16.0.7': + resolution: {integrity: sha512-gpaNgUh5nftFKRkRQGnVi5dpcYSKGcZZkQffZ172OrG/XkrnS7UBTQ648YY+8ME92cC4IojpI2LqTC8sTDhAaw==} '@next/rspack-binding-android-arm-eabi@1.0.1': resolution: {integrity: sha512-ZLEy3shsHk8FpJDeoU4gN3a7eVaOagA7AW2BXSVefBAO4hR6j3Kt/T732FUmf9G5328C2vsbMAWskHRHPbhTig==} @@ -4452,98 +4446,98 @@ packages: '@next/rspack-core@1.0.1': resolution: {integrity: sha512-08np3obem5g/ptYxybbD6ovZaNFrpA+6LL9OzwLNKX/zU5+rgg3CZR09xda9oIgtplTDCbZdB8nZffDoqpwQsw==} - '@next/swc-darwin-arm64@15.5.3': - resolution: {integrity: sha512-nzbHQo69+au9wJkGKTU9lP7PXv0d1J5ljFpvb+LnEomLtSbJkbZyEs6sbF3plQmiOB2l9OBtN2tNSvCH1nQ9Jg==} + '@next/swc-darwin-arm64@15.5.7': + resolution: {integrity: sha512-IZwtxCEpI91HVU/rAUOOobWSZv4P2DeTtNaCdHqLcTJU4wdNXgAySvKa/qJCgR5m6KI8UsKDXtO2B31jcaw1Yw==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] - '@next/swc-darwin-arm64@16.0.1': - resolution: {integrity: sha512-R0YxRp6/4W7yG1nKbfu41bp3d96a0EalonQXiMe+1H9GTHfKxGNCGFNWUho18avRBPsO8T3RmdWuzmfurlQPbg==} + '@next/swc-darwin-arm64@16.0.7': + resolution: {integrity: sha512-LlDtCYOEj/rfSnEn/Idi+j1QKHxY9BJFmxx7108A6D8K0SB+bNgfYQATPk/4LqOl4C0Wo3LACg2ie6s7xqMpJg==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] - '@next/swc-darwin-x64@15.5.3': - resolution: {integrity: sha512-w83w4SkOOhekJOcA5HBvHyGzgV1W/XvOfpkrxIse4uPWhYTTRwtGEM4v/jiXwNSJvfRvah0H8/uTLBKRXlef8g==} + '@next/swc-darwin-x64@15.5.7': + resolution: {integrity: sha512-UP6CaDBcqaCBuiq/gfCEJw7sPEoX1aIjZHnBWN9v9qYHQdMKvCKcAVs4OX1vIjeE+tC5EIuwDTVIoXpUes29lg==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] - '@next/swc-darwin-x64@16.0.1': - resolution: {integrity: sha512-kETZBocRux3xITiZtOtVoVvXyQLB7VBxN7L6EPqgI5paZiUlnsgYv4q8diTNYeHmF9EiehydOBo20lTttCbHAg==} + '@next/swc-darwin-x64@16.0.7': + resolution: {integrity: sha512-rtZ7BhnVvO1ICf3QzfW9H3aPz7GhBrnSIMZyr4Qy6boXF0b5E3QLs+cvJmg3PsTCG2M1PBoC+DANUi4wCOKXpA==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] - '@next/swc-linux-arm64-gnu@15.5.3': - resolution: {integrity: sha512-+m7pfIs0/yvgVu26ieaKrifV8C8yiLe7jVp9SpcIzg7XmyyNE7toC1fy5IOQozmr6kWl/JONC51osih2RyoXRw==} + '@next/swc-linux-arm64-gnu@15.5.7': + resolution: {integrity: sha512-NCslw3GrNIw7OgmRBxHtdWFQYhexoUCq+0oS2ccjyYLtcn1SzGzeM54jpTFonIMUjNbHmpKpziXnpxhSWLcmBA==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@next/swc-linux-arm64-gnu@16.0.1': - resolution: {integrity: sha512-hWg3BtsxQuSKhfe0LunJoqxjO4NEpBmKkE+P2Sroos7yB//OOX3jD5ISP2wv8QdUwtRehMdwYz6VB50mY6hqAg==} + '@next/swc-linux-arm64-gnu@16.0.7': + resolution: {integrity: sha512-mloD5WcPIeIeeZqAIP5c2kdaTa6StwP4/2EGy1mUw8HiexSHGK/jcM7lFuS3u3i2zn+xH9+wXJs6njO7VrAqww==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@next/swc-linux-arm64-musl@15.5.3': - resolution: {integrity: sha512-u3PEIzuguSenoZviZJahNLgCexGFhso5mxWCrrIMdvpZn6lkME5vc/ADZG8UUk5K1uWRy4hqSFECrON6UKQBbQ==} + '@next/swc-linux-arm64-musl@15.5.7': + resolution: {integrity: sha512-nfymt+SE5cvtTrG9u1wdoxBr9bVB7mtKTcj0ltRn6gkP/2Nu1zM5ei8rwP9qKQP0Y//umK+TtkKgNtfboBxRrw==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@next/swc-linux-arm64-musl@16.0.1': - resolution: {integrity: sha512-UPnOvYg+fjAhP3b1iQStcYPWeBFRLrugEyK/lDKGk7kLNua8t5/DvDbAEFotfV1YfcOY6bru76qN9qnjLoyHCQ==} + '@next/swc-linux-arm64-musl@16.0.7': + resolution: {integrity: sha512-+ksWNrZrthisXuo9gd1XnjHRowCbMtl/YgMpbRvFeDEqEBd523YHPWpBuDjomod88U8Xliw5DHhekBC3EOOd9g==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@next/swc-linux-x64-gnu@15.5.3': - resolution: {integrity: sha512-lDtOOScYDZxI2BENN9m0pfVPJDSuUkAD1YXSvlJF0DKwZt0WlA7T7o3wrcEr4Q+iHYGzEaVuZcsIbCps4K27sA==} + '@next/swc-linux-x64-gnu@15.5.7': + resolution: {integrity: sha512-hvXcZvCaaEbCZcVzcY7E1uXN9xWZfFvkNHwbe/n4OkRhFWrs1J1QV+4U1BN06tXLdaS4DazEGXwgqnu/VMcmqw==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@next/swc-linux-x64-gnu@16.0.1': - resolution: {integrity: sha512-Et81SdWkcRqAJziIgFtsFyJizHoWne4fzJkvjd6V4wEkWTB4MX6J0uByUb0peiJQ4WeAt6GGmMszE5KrXK6WKg==} + '@next/swc-linux-x64-gnu@16.0.7': + resolution: {integrity: sha512-4WtJU5cRDxpEE44Ana2Xro1284hnyVpBb62lIpU5k85D8xXxatT+rXxBgPkc7C1XwkZMWpK5rXLXTh9PFipWsA==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@next/swc-linux-x64-musl@15.5.3': - resolution: {integrity: sha512-9vWVUnsx9PrY2NwdVRJ4dUURAQ8Su0sLRPqcCCxtX5zIQUBES12eRVHq6b70bbfaVaxIDGJN2afHui0eDm+cLg==} + '@next/swc-linux-x64-musl@15.5.7': + resolution: {integrity: sha512-4IUO539b8FmF0odY6/SqANJdgwn1xs1GkPO5doZugwZ3ETF6JUdckk7RGmsfSf7ws8Qb2YB5It33mvNL/0acqA==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@next/swc-linux-x64-musl@16.0.1': - resolution: {integrity: sha512-qBbgYEBRrC1egcG03FZaVfVxrJm8wBl7vr8UFKplnxNRprctdP26xEv9nJ07Ggq4y1adwa0nz2mz83CELY7N6Q==} + '@next/swc-linux-x64-musl@16.0.7': + resolution: {integrity: sha512-HYlhqIP6kBPXalW2dbMTSuB4+8fe+j9juyxwfMwCe9kQPPeiyFn7NMjNfoFOfJ2eXkeQsoUGXg+O2SE3m4Qg2w==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@next/swc-win32-arm64-msvc@15.5.3': - resolution: {integrity: sha512-1CU20FZzY9LFQigRi6jM45oJMU3KziA5/sSG+dXeVaTm661snQP6xu3ykGxxwU5sLG3sh14teO/IOEPVsQMRfA==} + '@next/swc-win32-arm64-msvc@15.5.7': + resolution: {integrity: sha512-CpJVTkYI3ZajQkC5vajM7/ApKJUOlm6uP4BknM3XKvJ7VXAvCqSjSLmM0LKdYzn6nBJVSjdclx8nYJSa3xlTgQ==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] - '@next/swc-win32-arm64-msvc@16.0.1': - resolution: {integrity: sha512-cPuBjYP6I699/RdbHJonb3BiRNEDm5CKEBuJ6SD8k3oLam2fDRMKAvmrli4QMDgT2ixyRJ0+DTkiODbIQhRkeQ==} + '@next/swc-win32-arm64-msvc@16.0.7': + resolution: {integrity: sha512-EviG+43iOoBRZg9deGauXExjRphhuYmIOJ12b9sAPy0eQ6iwcPxfED2asb/s2/yiLYOdm37kPaiZu8uXSYPs0Q==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] - '@next/swc-win32-x64-msvc@15.5.3': - resolution: {integrity: sha512-JMoLAq3n3y5tKXPQwCK5c+6tmwkuFDa2XAxz8Wm4+IVthdBZdZGh+lmiLUHg9f9IDwIQpUjp+ysd6OkYTyZRZw==} + '@next/swc-win32-x64-msvc@15.5.7': + resolution: {integrity: sha512-gMzgBX164I6DN+9/PGA+9dQiwmTkE4TloBNx8Kv9UiGARsr9Nba7IpcBRA1iTV9vwlYnrE3Uy6I7Aj6qLjQuqw==} engines: {node: '>= 10'} cpu: [x64] os: [win32] - '@next/swc-win32-x64-msvc@16.0.1': - resolution: {integrity: sha512-XeEUJsE4JYtfrXe/LaJn3z1pD19fK0Q6Er8Qoufi+HqvdO4LEPyCxLUt4rxA+4RfYo6S9gMlmzCMU2F+AatFqQ==} + '@next/swc-win32-x64-msvc@16.0.7': + resolution: {integrity: sha512-gniPjy55zp5Eg0896qSrf3yB1dw4F/3s8VK1ephdsZZ129j2n6e1WqCbE2YgcKhW9hPB9TVZENugquWJD5x0ug==} engines: {node: '>= 10'} cpu: [x64] os: [win32] @@ -5549,106 +5543,6 @@ packages: resolution: {integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==} engines: {node: '>= 8.0.0'} - '@rollup/rollup-android-arm-eabi@4.39.0': - resolution: {integrity: sha512-lGVys55Qb00Wvh8DMAocp5kIcaNzEFTmGhfFd88LfaogYTRKrdxgtlO5H6S49v2Nd8R2C6wLOal0qv6/kCkOwA==} - cpu: [arm] - os: [android] - - '@rollup/rollup-android-arm64@4.39.0': - resolution: {integrity: sha512-It9+M1zE31KWfqh/0cJLrrsCPiF72PoJjIChLX+rEcujVRCb4NLQ5QzFkzIZW8Kn8FTbvGQBY5TkKBau3S8cCQ==} - cpu: [arm64] - os: [android] - - '@rollup/rollup-darwin-arm64@4.39.0': - resolution: {integrity: sha512-lXQnhpFDOKDXiGxsU9/l8UEGGM65comrQuZ+lDcGUx+9YQ9dKpF3rSEGepyeR5AHZ0b5RgiligsBhWZfSSQh8Q==} - cpu: [arm64] - os: [darwin] - - '@rollup/rollup-darwin-x64@4.39.0': - resolution: {integrity: sha512-mKXpNZLvtEbgu6WCkNij7CGycdw9cJi2k9v0noMb++Vab12GZjFgUXD69ilAbBh034Zwn95c2PNSz9xM7KYEAQ==} - cpu: [x64] - os: [darwin] - - '@rollup/rollup-freebsd-arm64@4.39.0': - resolution: {integrity: sha512-jivRRlh2Lod/KvDZx2zUR+I4iBfHcu2V/BA2vasUtdtTN2Uk3jfcZczLa81ESHZHPHy4ih3T/W5rPFZ/hX7RtQ==} - cpu: [arm64] - os: [freebsd] - - '@rollup/rollup-freebsd-x64@4.39.0': - resolution: {integrity: sha512-8RXIWvYIRK9nO+bhVz8DwLBepcptw633gv/QT4015CpJ0Ht8punmoHU/DuEd3iw9Hr8UwUV+t+VNNuZIWYeY7Q==} - cpu: [x64] - os: [freebsd] - - '@rollup/rollup-linux-arm-gnueabihf@4.39.0': - resolution: {integrity: sha512-mz5POx5Zu58f2xAG5RaRRhp3IZDK7zXGk5sdEDj4o96HeaXhlUwmLFzNlc4hCQi5sGdR12VDgEUqVSHer0lI9g==} - cpu: [arm] - os: [linux] - - '@rollup/rollup-linux-arm-musleabihf@4.39.0': - resolution: {integrity: sha512-+YDwhM6gUAyakl0CD+bMFpdmwIoRDzZYaTWV3SDRBGkMU/VpIBYXXEvkEcTagw/7VVkL2vA29zU4UVy1mP0/Yw==} - cpu: [arm] - os: [linux] - - '@rollup/rollup-linux-arm64-gnu@4.39.0': - resolution: {integrity: sha512-EKf7iF7aK36eEChvlgxGnk7pdJfzfQbNvGV/+l98iiMwU23MwvmV0Ty3pJ0p5WQfm3JRHOytSIqD9LB7Bq7xdQ==} - cpu: [arm64] - os: [linux] - - '@rollup/rollup-linux-arm64-musl@4.39.0': - resolution: {integrity: sha512-vYanR6MtqC7Z2SNr8gzVnzUul09Wi1kZqJaek3KcIlI/wq5Xtq4ZPIZ0Mr/st/sv/NnaPwy/D4yXg5x0B3aUUA==} - cpu: [arm64] - os: [linux] - - '@rollup/rollup-linux-loongarch64-gnu@4.39.0': - resolution: {integrity: sha512-NMRUT40+h0FBa5fb+cpxtZoGAggRem16ocVKIv5gDB5uLDgBIwrIsXlGqYbLwW8YyO3WVTk1FkFDjMETYlDqiw==} - cpu: [loong64] - os: [linux] - - '@rollup/rollup-linux-powerpc64le-gnu@4.39.0': - resolution: {integrity: sha512-0pCNnmxgduJ3YRt+D+kJ6Ai/r+TaePu9ZLENl+ZDV/CdVczXl95CbIiwwswu4L+K7uOIGf6tMo2vm8uadRaICQ==} - cpu: [ppc64] - os: [linux] - - '@rollup/rollup-linux-riscv64-gnu@4.39.0': - resolution: {integrity: sha512-t7j5Zhr7S4bBtksT73bO6c3Qa2AV/HqiGlj9+KB3gNF5upcVkx+HLgxTm8DK4OkzsOYqbdqbLKwvGMhylJCPhQ==} - cpu: [riscv64] - os: [linux] - - '@rollup/rollup-linux-riscv64-musl@4.39.0': - resolution: {integrity: sha512-m6cwI86IvQ7M93MQ2RF5SP8tUjD39Y7rjb1qjHgYh28uAPVU8+k/xYWvxRO3/tBN2pZkSMa5RjnPuUIbrwVxeA==} - cpu: [riscv64] - os: [linux] - - '@rollup/rollup-linux-s390x-gnu@4.39.0': - resolution: {integrity: sha512-iRDJd2ebMunnk2rsSBYlsptCyuINvxUfGwOUldjv5M4tpa93K8tFMeYGpNk2+Nxl+OBJnBzy2/JCscGeO507kA==} - cpu: [s390x] - os: [linux] - - '@rollup/rollup-linux-x64-gnu@4.39.0': - resolution: {integrity: sha512-t9jqYw27R6Lx0XKfEFe5vUeEJ5pF3SGIM6gTfONSMb7DuG6z6wfj2yjcoZxHg129veTqU7+wOhY6GX8wmf90dA==} - cpu: [x64] - os: [linux] - - '@rollup/rollup-linux-x64-musl@4.39.0': - resolution: {integrity: sha512-ThFdkrFDP55AIsIZDKSBWEt/JcWlCzydbZHinZ0F/r1h83qbGeenCt/G/wG2O0reuENDD2tawfAj2s8VK7Bugg==} - cpu: [x64] - os: [linux] - - '@rollup/rollup-win32-arm64-msvc@4.39.0': - resolution: {integrity: sha512-jDrLm6yUtbOg2TYB3sBF3acUnAwsIksEYjLeHL+TJv9jg+TmTwdyjnDex27jqEMakNKf3RwwPahDIt7QXCSqRQ==} - cpu: [arm64] - os: [win32] - - '@rollup/rollup-win32-ia32-msvc@4.39.0': - resolution: {integrity: sha512-6w9uMuza+LbLCVoNKL5FSLE7yvYkq9laSd09bwS0tMjkwXrmib/4KmoJcrKhLWHvw19mwU+33ndC69T7weNNjQ==} - cpu: [ia32] - os: [win32] - - '@rollup/rollup-win32-x64-msvc@4.39.0': - resolution: {integrity: sha512-yAkUOkIKZlK5dl7u6dg897doBgLXmUHhIINM2c+sND3DZwnrdQkkSiDh7N75Ll4mM4dxSkYfXqU9fW3lLkMFug==} - cpu: [x64] - os: [win32] - '@rspack/binding-darwin-arm64@1.6.0': resolution: {integrity: sha512-IrigOWnGvQgugsTZgf3dB5uko+y+lkNLYg/8w0DiobxkWhpLO97RAeR1w0ofIPXYVu3UWVf7dgHj3PjTqjC9Tw==} cpu: [arm64] @@ -6908,53 +6802,21 @@ packages: '@vitest/expect@2.0.5': resolution: {integrity: sha512-yHZtwuP7JZivj65Gxoi8upUN2OzHTi3zVfjwdpu2WrvCZPLwsJ2Ey5ILIPccoW23dd/zQBlJ4/dhi7DWNyXCpA==} - '@vitest/expect@3.0.4': - resolution: {integrity: sha512-Nm5kJmYw6P2BxhJPkO3eKKhGYKRsnqJqf+r0yOGRKpEP+bSCBDsjXgiu1/5QFrnPMEgzfC38ZEjvCFgaNBC0Eg==} - - '@vitest/mocker@3.0.4': - resolution: {integrity: sha512-gEef35vKafJlfQbnyOXZ0Gcr9IBUsMTyTLXsEQwuyYAerpHqvXhzdBnDFuHLpFqth3F7b6BaFr4qV/Cs1ULx5A==} - peerDependencies: - msw: ^2.4.9 - vite: ^5.0.0 || ^6.0.0 - peerDependenciesMeta: - msw: - optional: true - vite: - optional: true - '@vitest/pretty-format@2.0.5': resolution: {integrity: sha512-h8k+1oWHfwTkyTkb9egzwNMfJAEx4veaPSnMeKbVSjp4euqGSbQlm5+6VHwTr7u4FJslVVsUG5nopCaAYdOmSQ==} '@vitest/pretty-format@2.1.8': resolution: {integrity: sha512-9HiSZ9zpqNLKlbIDRWOnAWqgcA7xu+8YxXSekhr0Ykab7PAYFkhkwoqVArPOtJhPmYeE2YHgKZlj3CP36z2AJQ==} - '@vitest/pretty-format@3.0.4': - resolution: {integrity: sha512-ts0fba+dEhK2aC9PFuZ9LTpULHpY/nd6jhAQ5IMU7Gaj7crPCTdCFfgvXxruRBLFS+MLraicCuFXxISEq8C93g==} - - '@vitest/pretty-format@3.1.1': - resolution: {integrity: sha512-dg0CIzNx+hMMYfNmSqJlLSXEmnNhMswcn3sXO7Tpldr0LiGmg3eXdLLhwkv2ZqgHb/d5xg5F7ezNFRA1fA13yA==} - - '@vitest/runner@3.0.4': - resolution: {integrity: sha512-dKHzTQ7n9sExAcWH/0sh1elVgwc7OJ2lMOBrAm73J7AH6Pf9T12Zh3lNE1TETZaqrWFXtLlx3NVrLRb5hCK+iw==} - - '@vitest/snapshot@3.0.4': - resolution: {integrity: sha512-+p5knMLwIk7lTQkM3NonZ9zBewzVp9EVkVpvNta0/PlFWpiqLaRcF4+33L1it3uRUCh0BGLOaXPPGEjNKfWb4w==} - '@vitest/spy@2.0.5': resolution: {integrity: sha512-c/jdthAhvJdpfVuaexSrnawxZz6pywlTPe84LUB2m/4t3rl2fTo9NFGBG4oWgaD+FTgDDV8hJ/nibT7IfH3JfA==} - '@vitest/spy@3.0.4': - resolution: {integrity: sha512-sXIMF0oauYyUy2hN49VFTYodzEAu744MmGcPR3ZBsPM20G+1/cSW/n1U+3Yu/zHxX2bIDe1oJASOkml+osTU6Q==} - '@vitest/utils@2.0.5': resolution: {integrity: sha512-d8HKbqIcya+GR67mkZbrzhS5kKhtp8dQLcmRZLGTscGVg7yImT82cIrhtn2L8+VujWcy6KZweApgNmPsTAO/UQ==} '@vitest/utils@2.1.8': resolution: {integrity: sha512-dwSoui6djdwbfFmIgbIjX2ZhIoG7Ex/+xpxyiEgIGzjliY8xGkcpITKTlp6B4MgtGkF2ilvm97cPM96XZaAgcA==} - '@vitest/utils@3.0.4': - resolution: {integrity: sha512-8BqC1ksYsHtbWH+DfpOAKrFw3jl3Uf9J7yeFh85Pz52IWuh1hBBtyfEbRNNZNjl8H8A5yMLH9/t+k7HIKzQcZQ==} - '@webassemblyjs/ast@1.14.1': resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==} @@ -7809,10 +7671,6 @@ packages: resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} engines: {node: '>= 0.8'} - cac@6.7.14: - resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} - engines: {node: '>=8'} - cacache@15.3.0: resolution: {integrity: sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==} engines: {node: '>= 10'} @@ -7931,10 +7789,6 @@ packages: resolution: {integrity: sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw==} engines: {node: '>=12'} - chai@5.2.0: - resolution: {integrity: sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==} - engines: {node: '>=12'} - chalk@1.1.3: resolution: {integrity: sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==} engines: {node: '>=0.10.0'} @@ -9699,15 +9553,6 @@ packages: engines: {node: '>=6.0'} hasBin: true - eslint-config-next@16.1.0-canary.6: - resolution: {integrity: sha512-d1CjIey2sLh5WmnFVVVZJtES1MJs6VKxKhz/0DWZofhGaj6QbmiauQp6CAT7FwqSgikvwJvykL2nbJSrNnuKng==} - peerDependencies: - eslint: '>=9.0.0' - typescript: '>=3.3.1' - peerDependenciesMeta: - typescript: - optional: true - eslint-formatter-codeframe@7.32.1: resolution: {integrity: sha512-DK/3Q3+zVKq/7PdSYiCxPrsDF8H/TRMK5n8Hziwr4IMkMy+XiKSwbpj25AdajS63I/B61Snetq4uVvX9fOLyAg==} engines: {node: ^10.12.0 || >=12.0.0} @@ -9992,8 +9837,8 @@ packages: estree-util-to-js@2.0.0: resolution: {integrity: sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==} - estree-util-value-to-estree@3.4.0: - resolution: {integrity: sha512-Zlp+gxis+gCfK12d3Srl2PdX2ybsEA8ZYy6vQGVQTNNYLEGRQQ56XB64bjemN8kxIKXP1nC9ip4Z+ILy9LGzvQ==} + estree-util-value-to-estree@3.5.0: + resolution: {integrity: sha512-aMV56R27Gv3QmfmF1MY12GWkGzzeAezAX+UplqHVASfjc9wNzI/X6hC0S9oxq61WT4aQesLGslWP9tKk6ghRZQ==} estree-util-visit@1.2.1: resolution: {integrity: sha512-xbgqcrkIVbIG+lI/gzbvd9SGTJL4zqJKBFttUl5pP27KhAjtMKbX/mQXJ7qgyXpMgVy/zvpm0xoQQaGL8OloOw==} @@ -10090,10 +9935,6 @@ packages: expect-type@0.14.2: resolution: {integrity: sha512-ed3+tr5ujbIYXZ8Pl/VgIphwJQ0q5tBLGGdn7Zvwt1WyPBRX83xjT5pT77P/GkuQbctx0K2ZNSSan7eruJqTCQ==} - expect-type@1.2.1: - resolution: {integrity: sha512-/kP8CAwxzLVEeFrMm4kMmy4CCDlpipyA7MYLVrdJIkV0fYF0UaigQHRsxHiuY/GEea+bh4KSv3TIlgr+2UL6bw==} - engines: {node: '>=12.0.0'} - expect@29.5.0: resolution: {integrity: sha512-yM7xqUrCO2JdpFo4XpM82t+PJBFybdqoQuJLDGeDX2ij8NZzqRHyu3Hp188/JX7SWqud+7t4MUdvcgGBICMHZg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -12780,9 +12621,6 @@ packages: loupe@3.1.2: resolution: {integrity: sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==} - loupe@3.1.3: - resolution: {integrity: sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==} - lower-case@2.0.2: resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} @@ -13612,8 +13450,8 @@ packages: next-tick@1.0.0: resolution: {integrity: sha512-mc/caHeUcdjnC/boPWJefDr4KUIWQNv+tlnFnJd38QMou86QtxQzBJfxgGRzvx8jazYRqrVlaHarfO72uNxPOg==} - next@15.5.3: - resolution: {integrity: sha512-r/liNAx16SQj4D+XH/oI1dlpv9tdKJ6cONYPwwcCC46f2NjpaRWY+EKCzULfgQYV6YKXjHBchff2IZBSlZmJNw==} + next@15.5.7: + resolution: {integrity: sha512-+t2/0jIJ48kUpGKkdlhgkv+zPTEOoXyr60qXe68eB/pl3CMJaLeIGjzp5D6Oqt25hCBiBTt8wEeeAzfJvUKnPQ==} engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} hasBin: true peerDependencies: @@ -13633,8 +13471,8 @@ packages: sass: optional: true - next@16.0.1: - resolution: {integrity: sha512-e9RLSssZwd35p7/vOa+hoDFggUZIUbZhIUSLZuETCwrCVvxOs87NamoUzT+vbcNAL8Ld9GobBnWOA6SbV/arOw==} + next@16.0.7: + resolution: {integrity: sha512-3mBRJyPxT4LOxAJI6IsXeFtKfiJUbjCLgvXO02fV8Wy/lIhPvP94Fe7dGhUgHXcQy4sSuYwQNcOLhIfOm0rL0A==} engines: {node: '>=20.9.0'} hasBin: true peerDependencies: @@ -14368,9 +14206,6 @@ packages: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} - pathe@2.0.3: - resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} - pathval@2.0.0: resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} engines: {node: '>= 14.16'} @@ -15384,7 +15219,6 @@ packages: engines: {node: '>=0.6.0', teleport: '>=0.2.0'} deprecated: |- You or someone you depend on is using Q, the JavaScript Promise library that gave JavaScript developers strong feelings about promises. They can almost certainly migrate to the native JavaScript promise now. Thank you literally everyone for joining me in this bet against the odds. Be excellent to each other. - (For a CapTP with native promises, see @endo/eventual-send and @endo/captp) qs@6.11.0: @@ -16163,11 +15997,6 @@ packages: engines: {node: '>=10.0.0'} hasBin: true - rollup@4.39.0: - resolution: {integrity: sha512-thI8kNc02yNvnmJp8dr3fNWJ9tCONDhp6TV35X6HkKGGs9E6q7YWCHbe5vKiTa7TAiNcFEmXKj3X/pG2b3ci0g==} - engines: {node: '>=18.0.0', npm: '>=8.0.0'} - hasBin: true - router@2.2.0: resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} engines: {node: '>= 18'} @@ -16497,9 +16326,6 @@ packages: resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} engines: {node: '>= 0.4'} - siginfo@2.0.0: - resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} - signal-exit@3.0.3: resolution: {integrity: sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==} @@ -16728,9 +16554,6 @@ packages: resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} engines: {node: '>=10'} - stackback@0.0.2: - resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} - stacktrace-parser@0.1.10: resolution: {integrity: sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==} engines: {node: '>=6'} @@ -16746,9 +16569,6 @@ packages: resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} engines: {node: '>= 0.8'} - std-env@3.9.0: - resolution: {integrity: sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==} - stop-iteration-iterator@1.1.0: resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} engines: {node: '>= 0.4'} @@ -17276,35 +17096,22 @@ packages: tiny-invariant@1.3.3: resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} - tinybench@2.9.0: - resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} - tinydate@1.3.0: resolution: {integrity: sha512-7cR8rLy2QhYHpsBDBVYnnWXm8uRTr38RoZakFSW7Bs7PzfMPNZthuMLkwqZv7MTu8lhQ91cOFYS5a7iFj2oR3w==} engines: {node: '>=4'} - tinyexec@0.3.2: - resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} - - tinyexec@1.0.1: - resolution: {integrity: sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw==} + tinyexec@1.0.2: + resolution: {integrity: sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==} + engines: {node: '>=18'} tinyglobby@0.2.15: resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} engines: {node: '>=12.0.0'} - tinypool@1.0.2: - resolution: {integrity: sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==} - engines: {node: ^18.0.0 || >=20.0.0} - tinyrainbow@1.2.0: resolution: {integrity: sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==} engines: {node: '>=14.0.0'} - tinyrainbow@2.0.0: - resolution: {integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==} - engines: {node: '>=14.0.0'} - tinyspy@3.0.2: resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==} engines: {node: '>=14.0.0'} @@ -18100,79 +17907,6 @@ packages: vfile@6.0.3: resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} - vite-node@3.0.4: - resolution: {integrity: sha512-7JZKEzcYV2Nx3u6rlvN8qdo3QV7Fxyt6hx+CCKz9fbWxdX5IvUOmTWEAxMrWxaiSf7CKGLJQ5rFu8prb/jBjOA==} - engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} - hasBin: true - - vite@6.2.5: - resolution: {integrity: sha512-j023J/hCAa4pRIUH6J9HemwYfjB5llR2Ps0CWeikOtdR8+pAURAk0DoJC5/mm9kd+UgdnIy7d6HE4EAvlYhPhA==} - engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} - hasBin: true - peerDependencies: - '@types/node': 20.17.6 - jiti: '>=1.21.0' - less: '*' - lightningcss: ^1.21.0 - sass: '*' - sass-embedded: '*' - stylus: '*' - sugarss: '*' - terser: ^5.16.0 - tsx: ^4.8.1 - yaml: ^2.4.2 - peerDependenciesMeta: - '@types/node': - optional: true - jiti: - optional: true - less: - optional: true - lightningcss: - optional: true - sass: - optional: true - sass-embedded: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - tsx: - optional: true - yaml: - optional: true - - vitest@3.0.4: - resolution: {integrity: sha512-6XG8oTKy2gnJIFTHP6LD7ExFeNLxiTkK3CfMvT7IfR8IN+BYICCf0lXUQmX7i7JoxUP8QmeP4mTnWXgflu4yjw==} - engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} - hasBin: true - peerDependencies: - '@edge-runtime/vm': '*' - '@types/debug': ^4.1.12 - '@types/node': 20.17.6 - '@vitest/browser': 3.0.4 - '@vitest/ui': 3.0.4 - happy-dom: '*' - jsdom: '*' - peerDependenciesMeta: - '@edge-runtime/vm': - optional: true - '@types/debug': - optional: true - '@types/node': - optional: true - '@vitest/browser': - optional: true - '@vitest/ui': - optional: true - happy-dom: - optional: true - jsdom: - optional: true - vm-browserify@1.1.2: resolution: {integrity: sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==} @@ -18393,11 +18127,6 @@ packages: engines: {node: ^16.13.0 || >=18.0.0} hasBin: true - why-is-node-running@2.3.0: - resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} - engines: {node: '>=8'} - hasBin: true - wide-align@1.1.5: resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==} @@ -18650,8 +18379,8 @@ packages: zod@3.25.76: resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} - zod@4.1.9: - resolution: {integrity: sha512-HI32jTq0AUAC125z30E8bQNz0RQ+9Uc+4J7V97gLYjZVKRjeydPgGt6dvQzFrav7MYOUGFqqOGiHpA/fdbd0cQ==} + zod@4.1.13: + resolution: {integrity: sha512-AvvthqfqrAhNH9dnfmrfKzX5upOdjUVJYFqNSlkmGf64gRaTzlPwz99IHYnVs28qYAybvAlBV+H7pn0saFY4Ig==} zwitch@1.0.5: resolution: {integrity: sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==} @@ -18671,8 +18400,6 @@ snapshots: tunnel: 0.0.6 undici: 5.26.3 - '@adobe/css-tools@4.3.1': {} - '@adobe/css-tools@4.4.1': {} '@alloc/quick-lru@5.2.0': {} @@ -21572,13 +21299,9 @@ snapshots: '@tybys/wasm-util': 0.10.1 optional: true - '@next/env@15.5.3': {} + '@next/env@15.5.7': {} - '@next/env@16.0.1': {} - - '@next/eslint-plugin-next@16.1.0-canary.6': - dependencies: - fast-glob: 3.3.1 + '@next/env@16.0.7': {} '@next/rspack-binding-android-arm-eabi@1.0.1': optional: true @@ -21638,52 +21361,52 @@ snapshots: transitivePeerDependencies: - '@swc/helpers' - '@next/swc-darwin-arm64@15.5.3': + '@next/swc-darwin-arm64@15.5.7': optional: true - '@next/swc-darwin-arm64@16.0.1': + '@next/swc-darwin-arm64@16.0.7': optional: true - '@next/swc-darwin-x64@15.5.3': + '@next/swc-darwin-x64@15.5.7': optional: true - '@next/swc-darwin-x64@16.0.1': + '@next/swc-darwin-x64@16.0.7': optional: true - '@next/swc-linux-arm64-gnu@15.5.3': + '@next/swc-linux-arm64-gnu@15.5.7': optional: true - '@next/swc-linux-arm64-gnu@16.0.1': + '@next/swc-linux-arm64-gnu@16.0.7': optional: true - '@next/swc-linux-arm64-musl@15.5.3': + '@next/swc-linux-arm64-musl@15.5.7': optional: true - '@next/swc-linux-arm64-musl@16.0.1': + '@next/swc-linux-arm64-musl@16.0.7': optional: true - '@next/swc-linux-x64-gnu@15.5.3': + '@next/swc-linux-x64-gnu@15.5.7': optional: true - '@next/swc-linux-x64-gnu@16.0.1': + '@next/swc-linux-x64-gnu@16.0.7': optional: true - '@next/swc-linux-x64-musl@15.5.3': + '@next/swc-linux-x64-musl@15.5.7': optional: true - '@next/swc-linux-x64-musl@16.0.1': + '@next/swc-linux-x64-musl@16.0.7': optional: true - '@next/swc-win32-arm64-msvc@15.5.3': + '@next/swc-win32-arm64-msvc@15.5.7': optional: true - '@next/swc-win32-arm64-msvc@16.0.1': + '@next/swc-win32-arm64-msvc@16.0.7': optional: true - '@next/swc-win32-x64-msvc@15.5.3': + '@next/swc-win32-x64-msvc@15.5.7': optional: true - '@next/swc-win32-x64-msvc@16.0.1': + '@next/swc-win32-x64-msvc@16.0.7': optional: true '@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1': @@ -22781,66 +22504,6 @@ snapshots: estree-walker: 2.0.2 picomatch: 2.3.1 - '@rollup/rollup-android-arm-eabi@4.39.0': - optional: true - - '@rollup/rollup-android-arm64@4.39.0': - optional: true - - '@rollup/rollup-darwin-arm64@4.39.0': - optional: true - - '@rollup/rollup-darwin-x64@4.39.0': - optional: true - - '@rollup/rollup-freebsd-arm64@4.39.0': - optional: true - - '@rollup/rollup-freebsd-x64@4.39.0': - optional: true - - '@rollup/rollup-linux-arm-gnueabihf@4.39.0': - optional: true - - '@rollup/rollup-linux-arm-musleabihf@4.39.0': - optional: true - - '@rollup/rollup-linux-arm64-gnu@4.39.0': - optional: true - - '@rollup/rollup-linux-arm64-musl@4.39.0': - optional: true - - '@rollup/rollup-linux-loongarch64-gnu@4.39.0': - optional: true - - '@rollup/rollup-linux-powerpc64le-gnu@4.39.0': - optional: true - - '@rollup/rollup-linux-riscv64-gnu@4.39.0': - optional: true - - '@rollup/rollup-linux-riscv64-musl@4.39.0': - optional: true - - '@rollup/rollup-linux-s390x-gnu@4.39.0': - optional: true - - '@rollup/rollup-linux-x64-gnu@4.39.0': - optional: true - - '@rollup/rollup-linux-x64-musl@4.39.0': - optional: true - - '@rollup/rollup-win32-arm64-msvc@4.39.0': - optional: true - - '@rollup/rollup-win32-ia32-msvc@4.39.0': - optional: true - - '@rollup/rollup-win32-x64-msvc@4.39.0': - optional: true - '@rspack/binding-darwin-arm64@1.6.0': optional: true @@ -23542,26 +23205,25 @@ snapshots: lz-string: 1.5.0 pretty-format: 27.5.1 - '@testing-library/jest-dom@6.1.2(@jest/globals@29.7.0)(@types/jest@29.5.5)(jest@29.7.0(@types/node@20.17.6(patch_hash=rvl3vkomen3tospgr67bzubfyu))(babel-plugin-macros@3.1.0))(vitest@3.0.4(@types/node@20.17.6(patch_hash=rvl3vkomen3tospgr67bzubfyu))(jiti@2.5.1)(sass@1.54.0)(tsx@4.19.2))': + '@testing-library/jest-dom@6.1.2(@jest/globals@29.7.0)(@types/jest@29.5.5)(jest@29.7.0(@types/node@20.17.6(patch_hash=rvl3vkomen3tospgr67bzubfyu))(babel-plugin-macros@3.1.0))': dependencies: - '@adobe/css-tools': 4.3.1 + '@adobe/css-tools': 4.4.1 '@babel/runtime': 7.27.0 - aria-query: 5.3.0 + aria-query: 5.3.2 chalk: 3.0.0 css.escape: 1.5.1 - dom-accessibility-api: 0.5.13 + dom-accessibility-api: 0.5.16 lodash: 4.17.20 redent: 3.0.0 optionalDependencies: '@jest/globals': 29.7.0 '@types/jest': 29.5.5 jest: 29.7.0(@types/node@20.17.6(patch_hash=rvl3vkomen3tospgr67bzubfyu))(babel-plugin-macros@3.1.0) - vitest: 3.0.4(@types/node@20.17.6(patch_hash=rvl3vkomen3tospgr67bzubfyu))(jiti@2.5.1)(sass@1.54.0)(tsx@4.19.2) '@testing-library/jest-dom@6.5.0': dependencies: '@adobe/css-tools': 4.4.1 - aria-query: 5.3.0 + aria-query: 5.3.2 chalk: 3.0.0 css.escape: 1.5.1 dom-accessibility-api: 0.6.3 @@ -24312,23 +23974,6 @@ snapshots: chai: 5.1.2 tinyrainbow: 1.2.0 - '@vitest/expect@3.0.4': - dependencies: - '@vitest/spy': 3.0.4 - '@vitest/utils': 3.0.4 - chai: 5.2.0 - tinyrainbow: 2.0.0 - optional: true - - '@vitest/mocker@3.0.4(vite@6.2.5(@types/node@20.17.6(patch_hash=rvl3vkomen3tospgr67bzubfyu))(jiti@2.5.1)(sass@1.54.0)(tsx@4.19.2))': - dependencies: - '@vitest/spy': 3.0.4 - estree-walker: 3.0.3 - magic-string: 0.30.19 - optionalDependencies: - vite: 6.2.5(@types/node@20.17.6(patch_hash=rvl3vkomen3tospgr67bzubfyu))(jiti@2.5.1)(sass@1.54.0)(tsx@4.19.2) - optional: true - '@vitest/pretty-format@2.0.5': dependencies: tinyrainbow: 1.2.0 @@ -24337,38 +23982,10 @@ snapshots: dependencies: tinyrainbow: 1.2.0 - '@vitest/pretty-format@3.0.4': - dependencies: - tinyrainbow: 2.0.0 - optional: true - - '@vitest/pretty-format@3.1.1': - dependencies: - tinyrainbow: 2.0.0 - optional: true - - '@vitest/runner@3.0.4': - dependencies: - '@vitest/utils': 3.0.4 - pathe: 2.0.3 - optional: true - - '@vitest/snapshot@3.0.4': - dependencies: - '@vitest/pretty-format': 3.0.4 - magic-string: 0.30.19 - pathe: 2.0.3 - optional: true - '@vitest/spy@2.0.5': dependencies: tinyspy: 3.0.2 - '@vitest/spy@3.0.4': - dependencies: - tinyspy: 3.0.2 - optional: true - '@vitest/utils@2.0.5': dependencies: '@vitest/pretty-format': 2.0.5 @@ -24382,13 +23999,6 @@ snapshots: loupe: 3.1.2 tinyrainbow: 1.2.0 - '@vitest/utils@3.0.4': - dependencies: - '@vitest/pretty-format': 3.0.4 - loupe: 3.1.3 - tinyrainbow: 2.0.0 - optional: true - '@webassemblyjs/ast@1.14.1': dependencies: '@webassemblyjs/helper-numbers': 1.13.2 @@ -25381,9 +24991,6 @@ snapshots: bytes@3.1.2: {} - cac@6.7.14: - optional: true - cacache@15.3.0: dependencies: '@npmcli/fs': 1.1.1 @@ -25534,15 +25141,6 @@ snapshots: loupe: 3.1.2 pathval: 2.0.0 - chai@5.2.0: - dependencies: - assertion-error: 2.0.1 - check-error: 2.1.1 - deep-eql: 5.0.2 - loupe: 3.1.3 - pathval: 2.0.0 - optional: true - chalk@1.1.3: dependencies: ansi-styles: 2.2.1 @@ -27665,26 +27263,6 @@ snapshots: optionalDependencies: source-map: 0.6.1 - eslint-config-next@16.1.0-canary.6(eslint-plugin-import-x@4.3.1(eslint@9.37.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.37.0(jiti@2.5.1))(typescript@5.9.2): - dependencies: - '@next/eslint-plugin-next': 16.1.0-canary.6 - eslint: 9.37.0(jiti@2.5.1) - eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import-x@4.3.1(eslint@9.37.0(jiti@2.5.1))(typescript@5.9.2))(eslint-plugin-import@2.32.0(eslint@9.37.0(jiti@2.5.1)))(eslint@9.37.0(jiti@2.5.1)) - eslint-plugin-import: 2.32.0(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import-x@4.3.1(eslint@9.37.0(jiti@2.5.1))(typescript@5.9.2))(eslint-plugin-import@2.32.0(eslint@9.37.0(jiti@2.5.1)))(eslint@9.37.0(jiti@2.5.1)))(eslint@9.37.0(jiti@2.5.1)) - eslint-plugin-jsx-a11y: 6.10.2(eslint@9.37.0(jiti@2.5.1)) - eslint-plugin-react: 7.37.0(eslint@9.37.0(jiti@2.5.1)) - eslint-plugin-react-hooks: 7.0.0(eslint@9.37.0(jiti@2.5.1)) - globals: 16.4.0 - typescript-eslint: 8.46.0(eslint@9.37.0(jiti@2.5.1))(typescript@5.9.2) - optionalDependencies: - typescript: 5.9.2 - transitivePeerDependencies: - - '@typescript-eslint/parser' - - eslint-import-resolver-webpack - - eslint-plugin-import-x - - supports-color - eslint-formatter-codeframe@7.32.1: dependencies: '@babel/code-frame': 7.12.11 @@ -27698,22 +27276,6 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.10.1(eslint-plugin-import-x@4.3.1(eslint@9.37.0(jiti@2.5.1))(typescript@5.9.2))(eslint-plugin-import@2.32.0(eslint@9.37.0(jiti@2.5.1)))(eslint@9.37.0(jiti@2.5.1)): - dependencies: - '@nolyfill/is-core-module': 1.0.39 - debug: 4.4.0 - eslint: 9.37.0(jiti@2.5.1) - get-tsconfig: 4.12.0 - is-bun-module: 2.0.0 - stable-hash: 0.0.5 - tinyglobby: 0.2.15 - unrs-resolver: 1.11.1 - optionalDependencies: - eslint-plugin-import: 2.32.0(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import-x@4.3.1(eslint@9.37.0(jiti@2.5.1))(typescript@5.9.2))(eslint-plugin-import@2.32.0(eslint@9.37.0(jiti@2.5.1)))(eslint@9.37.0(jiti@2.5.1)))(eslint@9.37.0(jiti@2.5.1)) - eslint-plugin-import-x: 4.3.1(eslint@9.37.0(jiti@2.5.1))(typescript@5.9.2) - transitivePeerDependencies: - - supports-color - eslint-import-resolver-typescript@3.10.1(eslint-plugin-import-x@4.3.1(eslint@9.37.0(jiti@2.5.1))(typescript@5.9.2))(eslint-plugin-import@2.32.0)(eslint@9.37.0(jiti@2.5.1)): dependencies: '@nolyfill/is-core-module': 1.0.39 @@ -27771,16 +27333,6 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.1(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import-x@4.3.1(eslint@9.37.0(jiti@2.5.1))(typescript@5.9.2))(eslint-plugin-import@2.32.0(eslint@9.37.0(jiti@2.5.1)))(eslint@9.37.0(jiti@2.5.1)))(eslint@9.37.0(jiti@2.5.1)): - dependencies: - debug: 3.2.7 - optionalDependencies: - eslint: 9.37.0(jiti@2.5.1) - eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import-x@4.3.1(eslint@9.37.0(jiti@2.5.1))(typescript@5.9.2))(eslint-plugin-import@2.32.0(eslint@9.37.0(jiti@2.5.1)))(eslint@9.37.0(jiti@2.5.1)) - transitivePeerDependencies: - - supports-color - eslint-plugin-eslint-plugin@5.2.1(eslint@9.37.0(jiti@2.5.1)): dependencies: eslint: 9.37.0(jiti@2.5.1) @@ -27861,33 +27413,6 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-plugin-import@2.32.0(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import-x@4.3.1(eslint@9.37.0(jiti@2.5.1))(typescript@5.9.2))(eslint-plugin-import@2.32.0(eslint@9.37.0(jiti@2.5.1)))(eslint@9.37.0(jiti@2.5.1)))(eslint@9.37.0(jiti@2.5.1)): - dependencies: - '@rtsao/scc': 1.1.0 - array-includes: 3.1.9 - array.prototype.findlastindex: 1.2.6 - array.prototype.flat: 1.3.3 - array.prototype.flatmap: 1.3.3 - debug: 3.2.7 - doctrine: 2.1.0 - eslint: 9.37.0(jiti@2.5.1) - eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.1(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import-x@4.3.1(eslint@9.37.0(jiti@2.5.1))(typescript@5.9.2))(eslint-plugin-import@2.32.0(eslint@9.37.0(jiti@2.5.1)))(eslint@9.37.0(jiti@2.5.1)))(eslint@9.37.0(jiti@2.5.1)) - hasown: 2.0.2 - is-core-module: 2.16.1 - is-glob: 4.0.3 - minimatch: 3.1.2 - object.fromentries: 2.0.8 - object.groupby: 1.0.3 - object.values: 1.2.1 - semver: 6.3.1 - string.prototype.trimend: 1.0.9 - tsconfig-paths: 3.15.0 - transitivePeerDependencies: - - eslint-import-resolver-typescript - - eslint-import-resolver-webpack - - supports-color - eslint-plugin-jest@27.6.3(eslint@9.37.0(jiti@2.5.1))(jest@29.7.0(@types/node@20.17.6(patch_hash=rvl3vkomen3tospgr67bzubfyu))(babel-plugin-macros@3.1.0))(typescript@5.9.2): dependencies: '@typescript-eslint/utils': 5.62.0(eslint@9.37.0(jiti@2.5.1))(typescript@5.9.2) @@ -28216,7 +27741,7 @@ snapshots: astring: 1.8.4 source-map: 0.7.4 - estree-util-value-to-estree@3.4.0: + estree-util-value-to-estree@3.5.0: dependencies: '@types/estree': 1.0.7 @@ -28352,9 +27877,6 @@ snapshots: expect-type@0.14.2: {} - expect-type@1.2.1: - optional: true - expect@29.5.0: dependencies: '@jest/expect-utils': 29.7.0 @@ -28901,7 +28423,7 @@ snapshots: fsevents@2.3.3: optional: true - fumadocs-core@15.7.12(@types/react@19.2.2)(next@15.5.3(@babel/core@7.26.10)(@opentelemetry/api@1.6.0)(@playwright/test@1.51.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@0.0.0-experimental-3fde738-20250918)(react-dom@19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203))(react@19.3.0-canary-7dc903cd-20251203)(sass@1.77.8))(react-dom@19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203))(react@19.3.0-canary-7dc903cd-20251203): + fumadocs-core@15.7.12(@types/react@19.2.2)(next@15.5.7(@babel/core@7.26.10)(@opentelemetry/api@1.6.0)(@playwright/test@1.51.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@0.0.0-experimental-3fde738-20250918)(react-dom@19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203))(react@19.3.0-canary-7dc903cd-20251203)(sass@1.77.8))(react-dom@19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203))(react@19.3.0-canary-7dc903cd-20251203): dependencies: '@formatjs/intl-localematcher': 0.6.1 '@orama/orama': 3.1.13 @@ -28922,38 +28444,37 @@ snapshots: unist-util-visit: 5.0.0 optionalDependencies: '@types/react': 19.2.2 - next: 15.5.3(@babel/core@7.26.10)(@opentelemetry/api@1.6.0)(@playwright/test@1.51.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@0.0.0-experimental-3fde738-20250918)(react-dom@19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203))(react@19.3.0-canary-7dc903cd-20251203)(sass@1.77.8) + next: 15.5.7(@babel/core@7.26.10)(@opentelemetry/api@1.6.0)(@playwright/test@1.51.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@0.0.0-experimental-3fde738-20250918)(react-dom@19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203))(react@19.3.0-canary-7dc903cd-20251203)(sass@1.77.8) react: 19.3.0-canary-7dc903cd-20251203 react-dom: 19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203) transitivePeerDependencies: - supports-color - fumadocs-mdx@11.10.0(fumadocs-core@15.7.12(@types/react@19.2.2)(next@15.5.3(@babel/core@7.26.10)(@opentelemetry/api@1.6.0)(@playwright/test@1.51.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@0.0.0-experimental-3fde738-20250918)(react-dom@19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203))(react@19.3.0-canary-7dc903cd-20251203)(sass@1.77.8))(react-dom@19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203))(react@19.3.0-canary-7dc903cd-20251203))(next@15.5.3(@babel/core@7.26.10)(@opentelemetry/api@1.6.0)(@playwright/test@1.51.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@0.0.0-experimental-3fde738-20250918)(react-dom@19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203))(react@19.3.0-canary-7dc903cd-20251203)(sass@1.77.8))(react@19.3.0-canary-7dc903cd-20251203)(vite@6.2.5(@types/node@20.17.6(patch_hash=rvl3vkomen3tospgr67bzubfyu))(jiti@2.5.1)(sass@1.77.8)(tsx@4.19.2)): + fumadocs-mdx@11.10.0(fumadocs-core@15.7.12(@types/react@19.2.2)(next@15.5.7(@babel/core@7.26.10)(@opentelemetry/api@1.6.0)(@playwright/test@1.51.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@0.0.0-experimental-3fde738-20250918)(react-dom@19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203))(react@19.3.0-canary-7dc903cd-20251203)(sass@1.77.8))(react-dom@19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203))(react@19.3.0-canary-7dc903cd-20251203))(next@15.5.7(@babel/core@7.26.10)(@opentelemetry/api@1.6.0)(@playwright/test@1.51.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@0.0.0-experimental-3fde738-20250918)(react-dom@19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203))(react@19.3.0-canary-7dc903cd-20251203)(sass@1.77.8))(react@19.3.0-canary-7dc903cd-20251203): dependencies: '@mdx-js/mdx': 3.1.1 '@standard-schema/spec': 1.0.0 chokidar: 4.0.3 esbuild: 0.25.9 - estree-util-value-to-estree: 3.4.0 - fumadocs-core: 15.7.12(@types/react@19.2.2)(next@15.5.3(@babel/core@7.26.10)(@opentelemetry/api@1.6.0)(@playwright/test@1.51.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@0.0.0-experimental-3fde738-20250918)(react-dom@19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203))(react@19.3.0-canary-7dc903cd-20251203)(sass@1.77.8))(react-dom@19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203))(react@19.3.0-canary-7dc903cd-20251203) + estree-util-value-to-estree: 3.5.0 + fumadocs-core: 15.7.12(@types/react@19.2.2)(next@15.5.7(@babel/core@7.26.10)(@opentelemetry/api@1.6.0)(@playwright/test@1.51.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@0.0.0-experimental-3fde738-20250918)(react-dom@19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203))(react@19.3.0-canary-7dc903cd-20251203)(sass@1.77.8))(react-dom@19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203))(react@19.3.0-canary-7dc903cd-20251203) js-yaml: 4.1.0 lru-cache: 11.2.1 picocolors: 1.1.1 remark-mdx: 3.1.1 remark-parse: 11.0.0 - tinyexec: 1.0.1 + tinyexec: 1.0.2 tinyglobby: 0.2.15 unified: 11.0.5 unist-util-visit: 5.0.0 - zod: 4.1.9 + zod: 4.1.13 optionalDependencies: - next: 15.5.3(@babel/core@7.26.10)(@opentelemetry/api@1.6.0)(@playwright/test@1.51.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@0.0.0-experimental-3fde738-20250918)(react-dom@19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203))(react@19.3.0-canary-7dc903cd-20251203)(sass@1.77.8) + next: 15.5.7(@babel/core@7.26.10)(@opentelemetry/api@1.6.0)(@playwright/test@1.51.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@0.0.0-experimental-3fde738-20250918)(react-dom@19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203))(react@19.3.0-canary-7dc903cd-20251203)(sass@1.77.8) react: 19.3.0-canary-7dc903cd-20251203 - vite: 6.2.5(@types/node@20.17.6(patch_hash=rvl3vkomen3tospgr67bzubfyu))(jiti@2.5.1)(sass@1.77.8)(tsx@4.19.2) transitivePeerDependencies: - supports-color - fumadocs-ui@15.7.12(@types/react-dom@19.2.1(@types/react@19.2.2))(@types/react@19.2.2)(next@15.5.3(@babel/core@7.26.10)(@opentelemetry/api@1.6.0)(@playwright/test@1.51.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@0.0.0-experimental-3fde738-20250918)(react-dom@19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203))(react@19.3.0-canary-7dc903cd-20251203)(sass@1.77.8))(react-dom@19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203))(react@19.3.0-canary-7dc903cd-20251203)(tailwindcss@4.1.13): + fumadocs-ui@15.7.12(@types/react-dom@19.2.1(@types/react@19.2.2))(@types/react@19.2.2)(next@15.5.7(@babel/core@7.26.10)(@opentelemetry/api@1.6.0)(@playwright/test@1.51.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@0.0.0-experimental-3fde738-20250918)(react-dom@19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203))(react@19.3.0-canary-7dc903cd-20251203)(sass@1.77.8))(react-dom@19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203))(react@19.3.0-canary-7dc903cd-20251203)(tailwindcss@4.1.13): dependencies: '@radix-ui/react-accordion': 1.2.12(@types/react-dom@19.2.1(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203))(react@19.3.0-canary-7dc903cd-20251203) '@radix-ui/react-collapsible': 1.1.12(@types/react-dom@19.2.1(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203))(react@19.3.0-canary-7dc903cd-20251203) @@ -28966,7 +28487,7 @@ snapshots: '@radix-ui/react-slot': 1.2.3(@types/react@19.2.2)(react@19.3.0-canary-7dc903cd-20251203) '@radix-ui/react-tabs': 1.1.13(@types/react-dom@19.2.1(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203))(react@19.3.0-canary-7dc903cd-20251203) class-variance-authority: 0.7.1 - fumadocs-core: 15.7.12(@types/react@19.2.2)(next@15.5.3(@babel/core@7.26.10)(@opentelemetry/api@1.6.0)(@playwright/test@1.51.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@0.0.0-experimental-3fde738-20250918)(react-dom@19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203))(react@19.3.0-canary-7dc903cd-20251203)(sass@1.77.8))(react-dom@19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203))(react@19.3.0-canary-7dc903cd-20251203) + fumadocs-core: 15.7.12(@types/react@19.2.2)(next@15.5.7(@babel/core@7.26.10)(@opentelemetry/api@1.6.0)(@playwright/test@1.51.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@0.0.0-experimental-3fde738-20250918)(react-dom@19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203))(react@19.3.0-canary-7dc903cd-20251203)(sass@1.77.8))(react-dom@19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203))(react@19.3.0-canary-7dc903cd-20251203) lodash.merge: 4.6.2 next-themes: 0.4.6(react-dom@19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203))(react@19.3.0-canary-7dc903cd-20251203) postcss-selector-parser: 7.1.0 @@ -28977,7 +28498,7 @@ snapshots: tailwind-merge: 3.3.1 optionalDependencies: '@types/react': 19.2.2 - next: 15.5.3(@babel/core@7.26.10)(@opentelemetry/api@1.6.0)(@playwright/test@1.51.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@0.0.0-experimental-3fde738-20250918)(react-dom@19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203))(react@19.3.0-canary-7dc903cd-20251203)(sass@1.77.8) + next: 15.5.7(@babel/core@7.26.10)(@opentelemetry/api@1.6.0)(@playwright/test@1.51.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@0.0.0-experimental-3fde738-20250918)(react-dom@19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203))(react@19.3.0-canary-7dc903cd-20251203)(sass@1.77.8) tailwindcss: 4.1.13 transitivePeerDependencies: - '@mixedbread/sdk' @@ -31784,9 +31305,6 @@ snapshots: loupe@3.1.2: {} - loupe@3.1.3: - optional: true - lower-case@2.0.2: dependencies: tslib: 2.8.1 @@ -33183,9 +32701,9 @@ snapshots: next-tick@1.0.0: {} - next@15.5.3(@babel/core@7.26.10)(@opentelemetry/api@1.6.0)(@playwright/test@1.51.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@0.0.0-experimental-3fde738-20250918)(react-dom@19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203))(react@19.3.0-canary-7dc903cd-20251203)(sass@1.77.8): + next@15.5.7(@babel/core@7.26.10)(@opentelemetry/api@1.6.0)(@playwright/test@1.51.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@0.0.0-experimental-3fde738-20250918)(react-dom@19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203))(react@19.3.0-canary-7dc903cd-20251203)(sass@1.77.8): dependencies: - '@next/env': 15.5.3 + '@next/env': 15.5.7 '@swc/helpers': 0.5.15 caniuse-lite: 1.0.30001746 postcss: 8.4.31 @@ -33193,14 +32711,14 @@ snapshots: react-dom: 19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203) styled-jsx: 5.1.6(@babel/core@7.26.10)(babel-plugin-macros@3.1.0)(react@19.3.0-canary-7dc903cd-20251203) optionalDependencies: - '@next/swc-darwin-arm64': 15.5.3 - '@next/swc-darwin-x64': 15.5.3 - '@next/swc-linux-arm64-gnu': 15.5.3 - '@next/swc-linux-arm64-musl': 15.5.3 - '@next/swc-linux-x64-gnu': 15.5.3 - '@next/swc-linux-x64-musl': 15.5.3 - '@next/swc-win32-arm64-msvc': 15.5.3 - '@next/swc-win32-x64-msvc': 15.5.3 + '@next/swc-darwin-arm64': 15.5.7 + '@next/swc-darwin-x64': 15.5.7 + '@next/swc-linux-arm64-gnu': 15.5.7 + '@next/swc-linux-arm64-musl': 15.5.7 + '@next/swc-linux-x64-gnu': 15.5.7 + '@next/swc-linux-x64-musl': 15.5.7 + '@next/swc-win32-arm64-msvc': 15.5.7 + '@next/swc-win32-x64-msvc': 15.5.7 '@opentelemetry/api': 1.6.0 '@playwright/test': 1.51.1 babel-plugin-react-compiler: 0.0.0-experimental-3fde738-20250918 @@ -33210,9 +32728,9 @@ snapshots: - '@babel/core' - babel-plugin-macros - next@16.0.1(@babel/core@7.26.10)(@opentelemetry/api@1.6.0)(@playwright/test@1.51.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@0.0.0-experimental-3fde738-20250918)(react-dom@19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203))(react@19.3.0-canary-7dc903cd-20251203)(sass@1.77.8): + next@16.0.7(@babel/core@7.26.10)(@opentelemetry/api@1.6.0)(@playwright/test@1.51.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@0.0.0-experimental-3fde738-20250918)(react-dom@19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203))(react@19.3.0-canary-7dc903cd-20251203)(sass@1.77.8): dependencies: - '@next/env': 16.0.1 + '@next/env': 16.0.7 '@swc/helpers': 0.5.15 caniuse-lite: 1.0.30001746 postcss: 8.4.31 @@ -33220,14 +32738,14 @@ snapshots: react-dom: 19.3.0-canary-7dc903cd-20251203(react@19.3.0-canary-7dc903cd-20251203) styled-jsx: 5.1.6(@babel/core@7.26.10)(babel-plugin-macros@3.1.0)(react@19.3.0-canary-7dc903cd-20251203) optionalDependencies: - '@next/swc-darwin-arm64': 16.0.1 - '@next/swc-darwin-x64': 16.0.1 - '@next/swc-linux-arm64-gnu': 16.0.1 - '@next/swc-linux-arm64-musl': 16.0.1 - '@next/swc-linux-x64-gnu': 16.0.1 - '@next/swc-linux-x64-musl': 16.0.1 - '@next/swc-win32-arm64-msvc': 16.0.1 - '@next/swc-win32-x64-msvc': 16.0.1 + '@next/swc-darwin-arm64': 16.0.7 + '@next/swc-darwin-x64': 16.0.7 + '@next/swc-linux-arm64-gnu': 16.0.7 + '@next/swc-linux-arm64-musl': 16.0.7 + '@next/swc-linux-x64-gnu': 16.0.7 + '@next/swc-linux-x64-musl': 16.0.7 + '@next/swc-win32-arm64-msvc': 16.0.7 + '@next/swc-win32-x64-msvc': 16.0.7 '@opentelemetry/api': 1.6.0 '@playwright/test': 1.51.1 babel-plugin-react-compiler: 0.0.0-experimental-3fde738-20250918 @@ -34103,9 +33621,6 @@ snapshots: path-type@4.0.0: {} - pathe@2.0.3: - optional: true - pathval@2.0.0: {} pause-stream@0.0.11: @@ -36195,33 +35710,6 @@ snapshots: optionalDependencies: fsevents: 2.1.3 - rollup@4.39.0: - dependencies: - '@types/estree': 1.0.7 - optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.39.0 - '@rollup/rollup-android-arm64': 4.39.0 - '@rollup/rollup-darwin-arm64': 4.39.0 - '@rollup/rollup-darwin-x64': 4.39.0 - '@rollup/rollup-freebsd-arm64': 4.39.0 - '@rollup/rollup-freebsd-x64': 4.39.0 - '@rollup/rollup-linux-arm-gnueabihf': 4.39.0 - '@rollup/rollup-linux-arm-musleabihf': 4.39.0 - '@rollup/rollup-linux-arm64-gnu': 4.39.0 - '@rollup/rollup-linux-arm64-musl': 4.39.0 - '@rollup/rollup-linux-loongarch64-gnu': 4.39.0 - '@rollup/rollup-linux-powerpc64le-gnu': 4.39.0 - '@rollup/rollup-linux-riscv64-gnu': 4.39.0 - '@rollup/rollup-linux-riscv64-musl': 4.39.0 - '@rollup/rollup-linux-s390x-gnu': 4.39.0 - '@rollup/rollup-linux-x64-gnu': 4.39.0 - '@rollup/rollup-linux-x64-musl': 4.39.0 - '@rollup/rollup-win32-arm64-msvc': 4.39.0 - '@rollup/rollup-win32-ia32-msvc': 4.39.0 - '@rollup/rollup-win32-x64-msvc': 4.39.0 - fsevents: 2.3.3 - optional: true - router@2.2.0: dependencies: debug: 4.4.0 @@ -36676,9 +36164,6 @@ snapshots: side-channel-map: 1.0.1 side-channel-weakmap: 1.0.2 - siginfo@2.0.0: - optional: true - signal-exit@3.0.3: {} signal-exit@3.0.7: {} @@ -36934,9 +36419,6 @@ snapshots: dependencies: escape-string-regexp: 2.0.0 - stackback@0.0.2: - optional: true - stacktrace-parser@0.1.10(patch_hash=x5tdcojc7b5m2b5ojepbcdl36a): dependencies: type-fest: 0.7.1 @@ -36947,9 +36429,6 @@ snapshots: statuses@2.0.1: {} - std-env@3.9.0: - optional: true - stop-iteration-iterator@1.1.0: dependencies: es-errors: 1.3.0 @@ -37598,29 +37077,17 @@ snapshots: tiny-invariant@1.3.3: {} - tinybench@2.9.0: - optional: true - tinydate@1.3.0: {} - tinyexec@0.3.2: - optional: true - - tinyexec@1.0.1: {} + tinyexec@1.0.2: {} tinyglobby@0.2.15: dependencies: fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 - tinypool@1.0.2: - optional: true - tinyrainbow@1.2.0: {} - tinyrainbow@2.0.0: - optional: true - tinyspy@3.0.2: {} title-case@3.0.3: @@ -38507,93 +37974,6 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.2 - vite-node@3.0.4(@types/node@20.17.6(patch_hash=rvl3vkomen3tospgr67bzubfyu))(jiti@2.5.1)(sass@1.54.0)(tsx@4.19.2): - dependencies: - cac: 6.7.14 - debug: 4.4.0 - es-module-lexer: 1.6.0 - pathe: 2.0.3 - vite: 6.2.5(@types/node@20.17.6(patch_hash=rvl3vkomen3tospgr67bzubfyu))(jiti@2.5.1)(sass@1.54.0)(tsx@4.19.2) - transitivePeerDependencies: - - '@types/node' - - jiti - - less - - lightningcss - - sass - - sass-embedded - - stylus - - sugarss - - supports-color - - terser - - tsx - - yaml - optional: true - - vite@6.2.5(@types/node@20.17.6(patch_hash=rvl3vkomen3tospgr67bzubfyu))(jiti@2.5.1)(sass@1.54.0)(tsx@4.19.2): - dependencies: - esbuild: 0.25.9 - postcss: 8.5.3 - rollup: 4.39.0 - optionalDependencies: - '@types/node': 20.17.6(patch_hash=rvl3vkomen3tospgr67bzubfyu) - fsevents: 2.3.3 - jiti: 2.5.1 - sass: 1.54.0 - tsx: 4.19.2 - optional: true - - vite@6.2.5(@types/node@20.17.6(patch_hash=rvl3vkomen3tospgr67bzubfyu))(jiti@2.5.1)(sass@1.77.8)(tsx@4.19.2): - dependencies: - esbuild: 0.25.9 - postcss: 8.5.3 - rollup: 4.39.0 - optionalDependencies: - '@types/node': 20.17.6(patch_hash=rvl3vkomen3tospgr67bzubfyu) - fsevents: 2.3.3 - jiti: 2.5.1 - sass: 1.77.8 - tsx: 4.19.2 - optional: true - - vitest@3.0.4(@types/node@20.17.6(patch_hash=rvl3vkomen3tospgr67bzubfyu))(jiti@2.5.1)(sass@1.54.0)(tsx@4.19.2): - dependencies: - '@vitest/expect': 3.0.4 - '@vitest/mocker': 3.0.4(vite@6.2.5(@types/node@20.17.6(patch_hash=rvl3vkomen3tospgr67bzubfyu))(jiti@2.5.1)(sass@1.54.0)(tsx@4.19.2)) - '@vitest/pretty-format': 3.1.1 - '@vitest/runner': 3.0.4 - '@vitest/snapshot': 3.0.4 - '@vitest/spy': 3.0.4 - '@vitest/utils': 3.0.4 - chai: 5.2.0 - debug: 4.4.0 - expect-type: 1.2.1 - magic-string: 0.30.19 - pathe: 2.0.3 - std-env: 3.9.0 - tinybench: 2.9.0 - tinyexec: 0.3.2 - tinypool: 1.0.2 - tinyrainbow: 2.0.0 - vite: 6.2.5(@types/node@20.17.6(patch_hash=rvl3vkomen3tospgr67bzubfyu))(jiti@2.5.1)(sass@1.54.0)(tsx@4.19.2) - vite-node: 3.0.4(@types/node@20.17.6(patch_hash=rvl3vkomen3tospgr67bzubfyu))(jiti@2.5.1)(sass@1.54.0)(tsx@4.19.2) - why-is-node-running: 2.3.0 - optionalDependencies: - '@types/node': 20.17.6(patch_hash=rvl3vkomen3tospgr67bzubfyu) - transitivePeerDependencies: - - jiti - - less - - lightningcss - - msw - - sass - - sass-embedded - - stylus - - sugarss - - supports-color - - terser - - tsx - - yaml - optional: true - vm-browserify@1.1.2: {} w3c-xmlserializer@4.0.0: @@ -38962,12 +38342,6 @@ snapshots: dependencies: isexe: 3.1.1 - why-is-node-running@2.3.0: - dependencies: - siginfo: 2.0.0 - stackback: 0.0.2 - optional: true - wide-align@1.1.5: dependencies: string-width: 4.2.3 @@ -39000,7 +38374,7 @@ snapshots: dependencies: ansi-styles: 4.3.0 string-width: 4.2.3 - strip-ansi: 6.0.0 + strip-ansi: 6.0.1 wrap-ansi@8.1.0: dependencies: @@ -39214,7 +38588,7 @@ snapshots: zod@3.25.76: {} - zod@4.1.9: {} + zod@4.1.13: {} zwitch@1.0.5: {} diff --git a/test/rspack-dev-tests-manifest.json b/test/rspack-dev-tests-manifest.json index 99072c58efd4ab..a44f8ea7c9867c 100644 --- a/test/rspack-dev-tests-manifest.json +++ b/test/rspack-dev-tests-manifest.json @@ -600,6 +600,27 @@ "flakey": [], "runtimeError": false }, + "test/development/app-dir/cache-components-reused-promise/cache-components-reused-promise.test.ts": { + "passed": [ + "cache-components-dev-warmup - reused promise aborts dynamic promises when restarting the render" + ], + "failed": [], + "pending": [], + "flakey": [], + "runtimeError": false + }, + "test/development/app-dir/cache-components-tasks/cache-components-tasks.test.ts": { + "passed": [ + "cache-components-tasks - with runtime prefetch configs initial load setImmediate resolves between tasks", + "cache-components-tasks - with runtime prefetch configs navigation setImmediate resolves between tasks", + "cache-components-tasks - without runtime prefetch configs initial load setImmediate resolves between tasks", + "cache-components-tasks - without runtime prefetch configs navigation setImmediate resolves between tasks" + ], + "failed": [], + "pending": [], + "flakey": [], + "runtimeError": false + }, "test/development/app-dir/cache-components-warnings/cache-components.warnings.test.ts": { "passed": [], "failed": [], @@ -1189,14 +1210,13 @@ }, "test/development/app-hmr/hmr.test.ts": { "passed": [ + "app-dir-hmr filesystem changes can navigate cleanly to a page that requires a change in the Webpack runtime", "app-dir-hmr filesystem changes should have no unexpected action error for hmr", "app-dir-hmr filesystem changes should not break when renaming a folder", "app-dir-hmr filesystem changes should not continously poll when hitting a not found page", "app-dir-hmr filesystem changes should update server components after navigating to a page with a different runtime" ], - "failed": [ - "app-dir-hmr filesystem changes can navigate cleanly to a page that requires a change in the Webpack runtime" - ], + "failed": [], "pending": [], "flakey": [], "runtimeError": false diff --git a/test/unit/next-image-get-img-props.test.ts b/test/unit/next-image-get-img-props.test.ts index 3900b588e5ecaa..c9df4cb90dd411 100644 --- a/test/unit/next-image-get-img-props.test.ts +++ b/test/unit/next-image-get-img-props.test.ts @@ -640,7 +640,37 @@ describe('getImageProps()', () => { delete process.env.NEXT_DEPLOYMENT_ID } }) - it('should not add query string for relative local image when NEXT_DEPLOYMENT_ID defined', async () => { + it('should add query string for imported local image from microfrontend when NEXT_DEPLOYMENT_ID defined', async () => { + try { + process.env.NEXT_DEPLOYMENT_ID = 'dpl_123' + const { props } = getImageProps({ + alt: 'a nice desc', + src: '/microfrontend/_next/static/media/test.abc123.png', // simulating microfrontend path + width: 100, + height: 200, + }) + expect(warningMessages).toStrictEqual([]) + expect(Object.entries(props)).toStrictEqual([ + ['alt', 'a nice desc'], + ['loading', 'lazy'], + ['width', 100], + ['height', 200], + ['decoding', 'async'], + ['style', { color: 'transparent' }], + [ + 'srcSet', + '/_next/image?url=%2Fmicrofrontend%2F_next%2Fstatic%2Fmedia%2Ftest.abc123.png&w=128&q=75&dpl=dpl_123 1x, /_next/image?url=%2Fmicrofrontend%2F_next%2Fstatic%2Fmedia%2Ftest.abc123.png&w=256&q=75&dpl=dpl_123 2x', + ], + [ + 'src', + '/_next/image?url=%2Fmicrofrontend%2F_next%2Fstatic%2Fmedia%2Ftest.abc123.png&w=256&q=75&dpl=dpl_123', + ], + ]) + } finally { + delete process.env.NEXT_DEPLOYMENT_ID + } + }) + it('should add query string for relative local image when NEXT_DEPLOYMENT_ID defined', async () => { try { process.env.NEXT_DEPLOYMENT_ID = 'dpl_123' const { props } = getImageProps({ @@ -659,9 +689,9 @@ describe('getImageProps()', () => { ['style', { color: 'transparent' }], [ 'srcSet', - '/_next/image?url=%2Ftest.png&w=128&q=75 1x, /_next/image?url=%2Ftest.png&w=256&q=75 2x', + '/_next/image?url=%2Ftest.png&w=128&q=75&dpl=dpl_123 1x, /_next/image?url=%2Ftest.png&w=256&q=75&dpl=dpl_123 2x', ], - ['src', '/_next/image?url=%2Ftest.png&w=256&q=75'], + ['src', '/_next/image?url=%2Ftest.png&w=256&q=75&dpl=dpl_123'], ]) } finally { delete process.env.NEXT_DEPLOYMENT_ID @@ -697,4 +727,73 @@ describe('getImageProps()', () => { delete process.env.NEXT_DEPLOYMENT_ID } }) + it('should add query string with question mark for unoptimized relative svg when NEXT_DEPLOYMENT_ID defined', async () => { + try { + process.env.NEXT_DEPLOYMENT_ID = 'dpl_123' + const { props } = getImageProps({ + alt: 'a nice desc', + src: '/test.svg', + width: 100, + height: 200, + }) + expect(warningMessages).toStrictEqual([]) + expect(Object.entries(props)).toStrictEqual([ + ['alt', 'a nice desc'], + ['loading', 'lazy'], + ['width', 100], + ['height', 200], + ['decoding', 'async'], + ['style', { color: 'transparent' }], + ['src', '/test.svg?dpl=dpl_123'], + ]) + } finally { + delete process.env.NEXT_DEPLOYMENT_ID + } + }) + it('should add query string with ampersand for unoptimized relative svg when NEXT_DEPLOYMENT_ID defined', async () => { + try { + process.env.NEXT_DEPLOYMENT_ID = 'dpl_123' + const { props } = getImageProps({ + alt: 'a nice desc', + src: '/test.svg?v=1', + width: 100, + height: 200, + }) + expect(warningMessages).toStrictEqual([]) + expect(Object.entries(props)).toStrictEqual([ + ['alt', 'a nice desc'], + ['loading', 'lazy'], + ['width', 100], + ['height', 200], + ['decoding', 'async'], + ['style', { color: 'transparent' }], + ['src', '/test.svg?v=1&dpl=dpl_123'], + ]) + } finally { + delete process.env.NEXT_DEPLOYMENT_ID + } + }) + it('should not add query string for unoptimized absolute remote svg when NEXT_DEPLOYMENT_ID defined', async () => { + try { + process.env.NEXT_DEPLOYMENT_ID = 'dpl_123' + const { props } = getImageProps({ + alt: 'a nice desc', + src: 'http://example.com/test.svg', + width: 100, + height: 200, + }) + expect(warningMessages).toStrictEqual([]) + expect(Object.entries(props)).toStrictEqual([ + ['alt', 'a nice desc'], + ['loading', 'lazy'], + ['width', 100], + ['height', 200], + ['decoding', 'async'], + ['style', { color: 'transparent' }], + ['src', 'http://example.com/test.svg'], + ]) + } finally { + delete process.env.NEXT_DEPLOYMENT_ID + } + }) }) diff --git a/turbopack/crates/turbo-bincode/Cargo.toml b/turbopack/crates/turbo-bincode/Cargo.toml new file mode 100644 index 00000000000000..abac7b2d57c910 --- /dev/null +++ b/turbopack/crates/turbo-bincode/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "turbo-bincode" +version = "0.0.0" +description = "Utilities for bincode used in turbo-tasks and turbopack" +license = "MIT" +edition = "2024" + +[lib] + +[lints] +workspace = true + +[dependencies] +bincode = { workspace = true } +either = { workspace = true } +indexmap = { workspace = true } +mime = { workspace = true } +ringmap = { workspace = true } +serde = { workspace = true } +serde_json = { workspace = true } +smallvec = { workspace = true } diff --git a/turbopack/crates/turbo-bincode/src/lib.rs b/turbopack/crates/turbo-bincode/src/lib.rs new file mode 100644 index 00000000000000..a6569d1e873ae0 --- /dev/null +++ b/turbopack/crates/turbo-bincode/src/lib.rs @@ -0,0 +1,568 @@ +use ::smallvec::SmallVec; +use bincode::{ + BorrowDecode, Decode, Encode, + de::{BorrowDecoder, Decoder}, + enc::Encoder, + error::{DecodeError, EncodeError}, +}; + +pub mod indexmap { + use std::hash::{BuildHasher, Hash}; + + use ::indexmap::IndexMap; + + use super::*; + + pub fn encode(map: &IndexMap, encoder: &mut E) -> Result<(), EncodeError> + where + E: Encoder, + K: Encode, + V: Encode, + { + usize::encode(&map.len(), encoder)?; + for (k, v) in map { + K::encode(k, encoder)?; + V::encode(v, encoder)?; + } + Ok(()) + } + + pub fn decode(decoder: &mut D) -> Result, DecodeError> + where + D: Decoder, + K: Decode + Eq + Hash, + V: Decode, + S: BuildHasher + Default, + { + let len = usize::decode(decoder)?; + let mut map = IndexMap::with_capacity_and_hasher(len, Default::default()); + for _i in 0..len { + map.insert(K::decode(decoder)?, V::decode(decoder)?); + } + Ok(map) + } + + pub fn borrow_decode<'de, Context, D, K, V, S>( + decoder: &mut D, + ) -> Result, DecodeError> + where + D: BorrowDecoder<'de, Context = Context>, + K: BorrowDecode<'de, Context> + Eq + Hash, + V: BorrowDecode<'de, Context>, + S: BuildHasher + Default, + { + let len = usize::decode(decoder)?; + let mut map = IndexMap::with_capacity_and_hasher(len, Default::default()); + for _i in 0..len { + map.insert(K::borrow_decode(decoder)?, V::borrow_decode(decoder)?); + } + Ok(map) + } + + #[cfg(test)] + mod tests { + use bincode::{decode_from_slice, encode_to_vec}; + + use super::*; + + #[test] + fn test_roundtrip() { + let cfg = bincode::config::standard(); + + #[derive(Encode, Decode)] + struct Wrapper(#[bincode(with = "crate::indexmap")] IndexMap); + + let map1 = Wrapper(IndexMap::from([ + ("key1".to_string(), 12345u32), + ("key2".to_string(), 23456u32), + ])); + + let map2: Wrapper = decode_from_slice(&encode_to_vec(&map1, cfg).unwrap(), cfg) + .unwrap() + .0; + + assert_eq!(map1.0, map2.0); + } + } +} + +pub mod indexset { + use std::hash::{BuildHasher, Hash}; + + use ::indexmap::IndexSet; + + use super::*; + + pub fn encode(set: &IndexSet, encoder: &mut E) -> Result<(), EncodeError> + where + E: Encoder, + T: Encode, + { + usize::encode(&set.len(), encoder)?; + for item in set { + T::encode(item, encoder)?; + } + Ok(()) + } + + pub fn decode(decoder: &mut D) -> Result, DecodeError> + where + D: Decoder, + T: Decode + Eq + Hash, + S: BuildHasher + Default, + { + let len = usize::decode(decoder)?; + let mut set = IndexSet::with_capacity_and_hasher(len, Default::default()); + for _i in 0..len { + set.insert(T::decode(decoder)?); + } + Ok(set) + } + + pub fn borrow_decode<'de, Context, D, T, S>( + decoder: &mut D, + ) -> Result, DecodeError> + where + D: BorrowDecoder<'de, Context = Context>, + T: BorrowDecode<'de, Context> + Eq + Hash, + S: BuildHasher + Default, + { + let len = usize::decode(decoder)?; + let mut set = IndexSet::with_capacity_and_hasher(len, Default::default()); + for _i in 0..len { + set.insert(T::borrow_decode(decoder)?); + } + Ok(set) + } + + #[cfg(test)] + mod tests { + use bincode::{decode_from_slice, encode_to_vec}; + + use super::*; + + #[test] + fn test_roundtrip() { + let cfg = bincode::config::standard(); + + #[derive(Encode, Decode)] + struct Wrapper(#[bincode(with = "crate::indexset")] IndexSet); + + let set1 = Wrapper(IndexSet::from([ + "value1".to_string(), + "value2".to_string(), + "value3".to_string(), + ])); + + let set2: Wrapper = decode_from_slice(&encode_to_vec(&set1, cfg).unwrap(), cfg) + .unwrap() + .0; + + assert_eq!(set1.0, set2.0); + } + } +} + +pub mod ringset { + use std::hash::{BuildHasher, Hash}; + + use ::ringmap::RingSet; + + use super::*; + + pub fn encode(set: &RingSet, encoder: &mut E) -> Result<(), EncodeError> + where + E: Encoder, + T: Encode, + { + usize::encode(&set.len(), encoder)?; + for item in set { + T::encode(item, encoder)?; + } + Ok(()) + } + + pub fn decode(decoder: &mut D) -> Result, DecodeError> + where + D: Decoder, + T: Decode + Eq + Hash, + S: BuildHasher + Default, + { + let len = usize::decode(decoder)?; + let mut set = RingSet::with_capacity_and_hasher(len, Default::default()); + for _i in 0..len { + set.insert(T::decode(decoder)?); + } + Ok(set) + } + + pub fn borrow_decode<'de, Context, D, T, S>( + decoder: &mut D, + ) -> Result, DecodeError> + where + D: BorrowDecoder<'de, Context = Context>, + T: BorrowDecode<'de, Context> + Eq + Hash, + S: BuildHasher + Default, + { + let len = usize::decode(decoder)?; + let mut set = RingSet::with_capacity_and_hasher(len, Default::default()); + for _i in 0..len { + set.insert(T::borrow_decode(decoder)?); + } + Ok(set) + } + + #[cfg(test)] + mod tests { + use bincode::{decode_from_slice, encode_to_vec}; + + use super::*; + + #[test] + fn test_roundtrip() { + let cfg = bincode::config::standard(); + + #[derive(Encode, Decode)] + struct Wrapper(#[bincode(with = "crate::ringset")] RingSet); + + let set1 = Wrapper(RingSet::from([ + "value1".to_string(), + "value2".to_string(), + "value3".to_string(), + ])); + + let set2: Wrapper = decode_from_slice(&encode_to_vec(&set1, cfg).unwrap(), cfg) + .unwrap() + .0; + + assert_eq!(set1.0, set2.0); + } + } +} + +pub mod mime_option { + use std::str::FromStr; + + use mime::Mime; + + use super::*; + + pub fn encode(mime: &Option, encoder: &mut E) -> Result<(), EncodeError> { + let mime_str: Option<&str> = mime.as_ref().map(AsRef::as_ref); + Encode::encode(&mime_str, encoder) + } + + pub fn decode>( + decoder: &mut D, + ) -> Result, DecodeError> { + if let Some(mime_str) = as Decode>::decode(decoder)? { + Ok(Some( + Mime::from_str(&mime_str).map_err(|e| DecodeError::OtherString(e.to_string()))?, + )) + } else { + Ok(None) + } + } + + pub fn borrow_decode<'de, Context, D: BorrowDecoder<'de, Context = Context>>( + decoder: &mut D, + ) -> Result, DecodeError> { + decode(decoder) + } + + #[cfg(test)] + mod tests { + use bincode::{decode_from_slice, encode_to_vec}; + + use super::*; + + #[derive(Encode, Decode)] + struct Wrapper(#[bincode(with = "crate::mime_option")] Option); + + #[test] + fn test_roundtrip() { + let cfg = bincode::config::standard(); + + let mime1 = Wrapper(Some("text/html; charset=utf-8".parse().unwrap())); + + let mime2: Wrapper = decode_from_slice(&encode_to_vec(&mime1, cfg).unwrap(), cfg) + .unwrap() + .0; + + assert_eq!(mime1.0, mime2.0); + } + + #[test] + fn test_roundtrip_none() { + let cfg = bincode::config::standard(); + + let mime1 = Wrapper(None); + + let mime2: Wrapper = decode_from_slice(&encode_to_vec(&mime1, cfg).unwrap(), cfg) + .unwrap() + .0; + + assert_eq!(mime1.0, mime2.0); + } + } +} + +/// Encode/decode as a serialized string encoded using `serde_json`. +/// +/// This encodes less efficiently than `#[bincode(with_serde)]` would, but avoids [bincode's known +/// compatibility issues][serde-issues]. Use this for infrequently-serialized types and when you're +/// unsure if the underlying type may trigger a serde compatibility issue. +/// +/// In the future this could be replaced with a more efficient serde-compatible self-describing +/// format with a compact binary representation (e.g. pot or MessagePack), but `serde_json` is +/// convenient because it avoids introducing additional dependencies. +/// +/// [serde-issues]: https://docs.rs/bincode/latest/bincode/serde/index.html#known-issues +pub mod serde_json { + use super::*; + + pub fn encode( + value: &T, + encoder: &mut E, + ) -> Result<(), EncodeError> { + let json_str = + ::serde_json::to_string(value).map_err(|e| EncodeError::OtherString(e.to_string()))?; + Encode::encode(&json_str, encoder) + } + + pub fn decode, T: serde::de::DeserializeOwned>( + decoder: &mut D, + ) -> Result { + let json_str: String = Decode::decode(decoder)?; + ::serde_json::from_str(&json_str).map_err(|e| DecodeError::OtherString(e.to_string())) + } + + pub fn borrow_decode< + 'de, + Context, + D: BorrowDecoder<'de, Context = Context>, + T: serde::de::Deserialize<'de>, + >( + decoder: &mut D, + ) -> Result { + let json_str: &str = BorrowDecode::borrow_decode(decoder)?; + ::serde_json::from_str(json_str).map_err(|e| DecodeError::OtherString(e.to_string())) + } + + #[cfg(test)] + mod tests { + use ::serde_json::{Value, json}; + use bincode::{decode_from_slice, encode_to_vec}; + + use super::*; + + #[test] + fn test_roundtrip() { + let cfg = bincode::config::standard(); + + #[derive(Encode, Decode)] + struct Wrapper(#[bincode(with = "crate::serde_json")] Value); + + let value1 = Wrapper(json!({ + "key1": [1, 2, 3], + "key2": [4, 5, 6] + })); + + let value2: Wrapper = decode_from_slice(&encode_to_vec(&value1, cfg).unwrap(), cfg) + .unwrap() + .0; + + assert_eq!(value1.0, value2.0); + } + } +} + +pub mod either { + use ::either::Either; + + use super::*; + + pub fn encode( + value: &Either, + encoder: &mut E, + ) -> Result<(), EncodeError> { + value.is_left().encode(encoder)?; + ::either::for_both!(value, v => Encode::encode(v, encoder)) + } + + pub fn decode< + Context, + D: Decoder, + L: Decode, + R: Decode, + >( + decoder: &mut D, + ) -> Result, DecodeError> { + let is_left = bool::decode(decoder)?; + Ok(if is_left { + Either::Left(L::decode(decoder)?) + } else { + Either::Right(R::decode(decoder)?) + }) + } + + pub fn borrow_decode< + 'de, + Context, + D: BorrowDecoder<'de, Context = Context>, + L: BorrowDecode<'de, Context>, + R: BorrowDecode<'de, Context>, + >( + decoder: &mut D, + ) -> Result, DecodeError> { + let is_left = bool::borrow_decode(decoder)?; + Ok(if is_left { + Either::Left(L::borrow_decode(decoder)?) + } else { + Either::Right(R::borrow_decode(decoder)?) + }) + } + + #[cfg(test)] + mod tests { + use bincode::{decode_from_slice, encode_to_vec}; + + use super::*; + + #[derive(Encode, Decode)] + struct Wrapper(#[bincode(with = "crate::either")] Either); + + #[test] + fn test_roundtrip_left() { + let cfg = bincode::config::standard(); + + let either1 = Wrapper(Either::Left("hello".to_string())); + + let either2: Wrapper = decode_from_slice(&encode_to_vec(&either1, cfg).unwrap(), cfg) + .unwrap() + .0; + + assert_eq!(either1.0, either2.0); + } + + #[test] + fn test_roundtrip_right() { + let cfg = bincode::config::standard(); + + let either1 = Wrapper(Either::Right(42u32)); + + let either2: Wrapper = decode_from_slice(&encode_to_vec(&either1, cfg).unwrap(), cfg) + .unwrap() + .0; + + assert_eq!(either1.0, either2.0); + } + } +} + +pub mod smallvec { + use ::smallvec::Array; + + use super::*; + + pub fn encode>( + vec: &SmallVec, + encoder: &mut E, + ) -> Result<(), EncodeError> { + usize::encode(&vec.len(), encoder)?; + for item in vec { + Encode::encode(item, encoder)?; + } + Ok(()) + } + + pub fn decode, A: Array>>( + decoder: &mut D, + ) -> Result, DecodeError> { + let len = usize::decode(decoder)?; + let mut vec = SmallVec::with_capacity(len); + for _ in 0..len { + vec.push(Decode::decode(decoder)?); + } + Ok(vec) + } + + pub fn borrow_decode< + 'de, + Context, + D: BorrowDecoder<'de, Context = Context>, + A: Array>, + >( + decoder: &mut D, + ) -> Result, DecodeError> { + let len = usize::decode(decoder)?; + let mut vec = SmallVec::with_capacity(len); + for _ in 0..len { + vec.push(BorrowDecode::borrow_decode(decoder)?); + } + Ok(vec) + } + + #[cfg(test)] + mod tests { + use bincode::{decode_from_slice, encode_to_vec}; + + use super::*; + + #[test] + fn test_roundtrip() { + let cfg = bincode::config::standard(); + + #[derive(Encode, Decode)] + struct Wrapper(#[bincode(with = "crate::smallvec")] SmallVec<[u32; 4]>); + + let vec1 = Wrapper(SmallVec::from_slice(&[1u32, 2, 3, 4, 5])); + + let vec2: Wrapper = decode_from_slice(&encode_to_vec(&vec1, cfg).unwrap(), cfg) + .unwrap() + .0; + + assert_eq!(vec1.0, vec2.0); + } + } +} + +pub mod owned_cow { + //! Overrides the default [`BorrowDecode`] implementation to always use the owned representation + //! of [`Cow`], so that the resulting [`BorrowDecode`] type is independent of the [`Cow`]'s + //! lifetime. + + use std::borrow::Cow; + + use super::*; + + #[allow(clippy::ptr_arg)] + pub fn encode(cow: &Cow<'_, T>, encoder: &mut E) -> Result<(), EncodeError> + where + E: Encoder, + T: ToOwned + ?Sized, + for<'a> &'a T: Encode, + { + cow.encode(encoder) + } + + pub fn decode<'cow, Context, D, T>(decoder: &mut D) -> Result, DecodeError> + where + D: Decoder, + T: ToOwned + ?Sized, + ::Owned: Decode, + { + Decode::decode(decoder) + } + + pub fn borrow_decode<'de, 'cow, Context, D, T>( + decoder: &mut D, + ) -> Result, DecodeError> + where + D: BorrowDecoder<'de, Context = Context>, + T: ToOwned + ?Sized, + ::Owned: Decode, + { + Decode::decode(decoder) + } +} diff --git a/turbopack/crates/turbo-tasks-fs/src/lib.rs b/turbopack/crates/turbo-tasks-fs/src/lib.rs index e9f575c565cfca..2caf3dcf0a2a3a 100644 --- a/turbopack/crates/turbo-tasks-fs/src/lib.rs +++ b/turbopack/crates/turbo-tasks-fs/src/lib.rs @@ -1912,7 +1912,7 @@ impl File { } /// Returns a Read/AsyncRead/Stream/Iterator to access the File's contents. - pub fn read(&self) -> RopeReader { + pub fn read(&self) -> RopeReader<'_> { self.content.read() } } diff --git a/turbopack/crates/turbo-tasks-fs/src/rope.rs b/turbopack/crates/turbo-tasks-fs/src/rope.rs index 9d49f8e48e3d8f..617d50ca5a104a 100644 --- a/turbopack/crates/turbo-tasks-fs/src/rope.rs +++ b/turbopack/crates/turbo-tasks-fs/src/rope.rs @@ -11,7 +11,7 @@ use std::{ use RopeElem::{Local, Shared}; use anyhow::{Context, Result}; -use bytes::{Buf, Bytes}; +use bytes::Bytes; use futures::Stream; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde_bytes::ByteBuf; @@ -103,7 +103,7 @@ impl Rope { } /// Returns a [Read]/[AsyncRead]/[Iterator] instance over all bytes. - pub fn read(&self) -> RopeReader { + pub fn read(&self) -> RopeReader<'_> { RopeReader::new(&self.data, 0) } @@ -688,28 +688,30 @@ impl DeterministicHash for RopeElem { #[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, +pub struct RopeReader<'a> { + /// The Rope's tree is kept as a stack, allowing us to accomplish incremental yielding. + stack: Vec>, + /// An offset in the current buffer, used by the `read` implementation. + offset: usize, } /// 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), +enum StackElem<'a> { + Local(&'a Bytes), + Shared(&'a InnerRope, usize), } -impl RopeReader { - fn new(inner: &InnerRope, index: usize) -> Self { +impl<'a> RopeReader<'a> { + fn new(inner: &'a InnerRope, index: usize) -> Self { if index >= inner.len() { Default::default() } else { RopeReader { - stack: vec![StackElem::Shared(inner.clone(), index)], + stack: vec![StackElem::Shared(inner, index)], + offset: 0, } } } @@ -720,30 +722,30 @@ impl RopeReader { let mut remaining = want; while remaining > 0 { - let mut bytes = match self.next() { + let bytes = match self.next_internal() { None => break, Some(b) => b, }; - let amount = min(bytes.len(), remaining); + let lower = self.offset; + let upper = min(bytes.len(), lower + remaining); - buf.put_slice(&bytes[0..amount]); + buf.put_slice(&bytes[self.offset..upper]); - if amount < bytes.len() { - bytes.advance(amount); + if upper < bytes.len() { + self.offset = upper; self.stack.push(StackElem::Local(bytes)) + } else { + self.offset = 0; } - remaining -= amount; + remaining -= upper - lower; } want - remaining } -} -impl Iterator for RopeReader { - type Item = Bytes; - - fn next(&mut self) -> Option { + /// Returns the next item in the iterator without modifying `self.offset`. + fn next_internal(&mut self) -> Option<&'a Bytes> { // Iterates the rope's elements recursively until we find the next Local // section, returning its Bytes. loop { @@ -756,7 +758,7 @@ impl Iterator for RopeReader { Some(StackElem::Shared(r, i)) => (r, i), }; - let el = inner[index].clone(); + let el = &inner[index]; index += 1; if index < inner.len() { self.stack.push(StackElem::Shared(inner, index)); @@ -767,13 +769,22 @@ impl Iterator for RopeReader { } } -impl Read for RopeReader { +impl<'a> Iterator for RopeReader<'a> { + type Item = &'a Bytes; + + fn next(&mut self) -> Option { + self.offset = 0; + self.next_internal() + } +} + +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 { +impl AsyncRead for RopeReader<'_> { fn poll_read( self: Pin<&mut Self>, _cx: &mut TaskContext<'_>, @@ -785,12 +796,12 @@ impl AsyncRead for RopeReader { } } -impl BufRead for RopeReader { +impl BufRead for RopeReader<'_> { /// Never returns an error. 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() { + let bytes = match self.next_internal() { None => return Ok(EMPTY_BUF), Some(b) => b, }; @@ -803,37 +814,44 @@ impl BufRead for RopeReader { unreachable!() }; - Ok(bytes) + Ok(&bytes[self.offset..]) } fn consume(&mut self, amt: usize) { if let Some(StackElem::Local(b)) = self.stack.last_mut() { - if amt == b.len() { + // https://doc.rust-lang.org/std/io/trait.BufRead.html#tymethod.consume + debug_assert!( + self.offset + amt <= b.len(), + "It is a logic error if `amount` exceeds the number of unread bytes in the \ + internal buffer, which is returned by `fill_buf`." + ); + // Consume some amount of bytes from the current Bytes instance, ensuring those bytes + // are not returned on the next call to `fill_buf`. + self.offset += amt; + if self.offset == b.len() { + // whole Bytes instance was consumed 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); + self.offset = 0; } } } } -impl Stream for RopeReader { - // The Result item type is required for this to be streamable into a - // [Hyper::Body]. - type Item = Result; +impl<'a> Stream for RopeReader<'a> { + /// This is efficiently streamable into a [`Hyper::Body`] if each item is cloned into an owned + /// `Bytes` instance. + type Item = Result<&'a Bytes>; - // Returns a "result" of reading the next shared bytes reference. This - // differs from [Read::read] by not copying any memory. + /// 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 { +impl<'a> From<&'a RopeElem> for StackElem<'a> { + fn from(el: &'a RopeElem) -> Self { match el { Local(bytes) => Self::Local(bytes), Shared(inner) => Self::Shared(inner, 0), diff --git a/turbopack/crates/turbopack-dev-server/Cargo.toml b/turbopack/crates/turbopack-dev-server/Cargo.toml index 25f4af60201b73..e9aeda6f3fefd8 100644 --- a/turbopack/crates/turbopack-dev-server/Cargo.toml +++ b/turbopack/crates/turbopack-dev-server/Cargo.toml @@ -17,8 +17,8 @@ workspace = true [dependencies] anyhow = { workspace = true } -async-compression = { workspace = true } auto-hash-map = { workspace = true } +flate2 = { workspace = true } futures = { workspace = true } hyper = { version = "0.14", features = ["full"] } hyper-tungstenite = "0.9.0" diff --git a/turbopack/crates/turbopack-dev-server/src/http.rs b/turbopack/crates/turbopack-dev-server/src/http.rs index ba0215a4465a34..e8b31c08dd2a3b 100644 --- a/turbopack/crates/turbopack-dev-server/src/http.rs +++ b/turbopack/crates/turbopack-dev-server/src/http.rs @@ -1,13 +1,15 @@ +use std::{io::Read, iter}; + use anyhow::{Result, anyhow}; use auto_hash_map::AutoSet; -use futures::{StreamExt, TryStreamExt}; +use flate2::{Compression, bufread::GzEncoder}; +use futures::{StreamExt, TryStreamExt, stream}; use hyper::{ Request, Response, header::{CONTENT_ENCODING, CONTENT_LENGTH, HeaderName}, http::HeaderValue, }; use mime::Mime; -use tokio_util::io::{ReaderStream, StreamReader}; use turbo_tasks::{ CollectiblesSource, OperationVc, ReadRef, ResolvedVc, TransientInstance, Vc, apply_effects, util::SharedError, @@ -175,22 +177,30 @@ pub async fn process_request_with_content_source( 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(std::io::Error::other); - - let gzipped_stream = - ReaderStream::new(async_compression::tokio::bufread::GzipEncoder::new( - StreamReader::new(stream_ext), - )); - - response.body(hyper::Body::wrap_stream(gzipped_stream))? + // Hyper requires an owned reader... We could do this with streaming by cloning + // each `Bytes` and implementing `BufRead` for `Iterator`, but + // it's not really worth it, just compressing the whole thing up-front is fine. + // + // Use fast compression, since we're likely just tranferring data over + // localhost. + let mut gz_bytes = Vec::new(); + GzEncoder::new(content.read(), Compression::fast()) + .read_to_end(&mut gz_bytes) + .expect("read of Rope should never fail"); + response.body(hyper::Body::wrap_stream(stream::iter(iter::once( + hyper::Result::Ok(gz_bytes), + ))))? } else { + // hyper requires an owned stream, so we must clone the iterator items + // this is relatively cheap: each chunk is a `Bytes`, so `Clone` updates a + // refcount + let owned_chunks: Vec<_> = + content.read().cloned().map(hyper::Result::Ok).collect(); header_map.insert( CONTENT_LENGTH, hyper::header::HeaderValue::try_from(content.len().to_string())?, ); - - response.body(hyper::Body::wrap_stream(content.read()))? + response.body(hyper::Body::wrap_stream(stream::iter(owned_chunks)))? }; return Ok((response, side_effects));