diff --git a/.cargo/config.toml b/.cargo/config.toml index 58c4ba6e7868f..1a821b151c4aa 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -15,11 +15,18 @@ rustdocflags = ["-Znormalize-docs"] [target.x86_64-pc-windows-msvc] linker = "rust-lld" -[target.aarch64-apple-darwin] +[target.'cfg(target_os = "macos")'] linker = "rust-lld" -[target.x86_64-apple-darwin] -linker = "rust-lld" +[target.'cfg(all(target_os = "linux", target_env = "gnu"))'] +rustflags = [ + "--cfg", + "tokio_unstable", + "-Zshare-generics=y", + "-Zthreads=8", + "-Csymbol-mangling-version=v0", + "-Clink-arg=-fuse-ld=lld", +] [alias] xtask = "run --package xtask --" diff --git a/.github/actions/setup-rust/action.yml b/.github/actions/setup-rust/action.yml index 7c6039ae6b3eb..ba8cc849622bf 100644 --- a/.github/actions/setup-rust/action.yml +++ b/.github/actions/setup-rust/action.yml @@ -34,6 +34,11 @@ runs: # we want more specific settings cache: false + - name: "Install LLD (LLVM Linker) for Linux" + if: runner.os == 'Linux' + shell: bash + run: sudo apt-get -y update && sudo apt-get install -y lld + - name: "Set Windows default host to MinGW" if: ${{ inputs.windows == 'true' }} shell: bash @@ -42,16 +47,16 @@ runs: - name: Set Up Protoc id: set-up-protoc continue-on-error: true - uses: arduino/setup-protoc@v1.2.0 + uses: arduino/setup-protoc@v2.1.0 with: - version: "3.x" + version: "26.x" repo-token: ${{ inputs.github-token }} - name: Set Up Protoc (second try) if: steps.set-up-protoc.outcome == 'failure' - uses: arduino/setup-protoc@v1.2.0 + uses: arduino/setup-protoc@v2.1.0 with: - version: "3.x" + version: "26.x" repo-token: ${{ inputs.github-token }} - name: "Add cargo problem matchers" diff --git a/.github/turbo-orchestrator.yml b/.github/turbo-orchestrator.yml index b6beaebc72d88..26c621b3144d9 100644 --- a/.github/turbo-orchestrator.yml +++ b/.github/turbo-orchestrator.yml @@ -44,7 +44,12 @@ labeler: isPRAuthorMatch: "^(bgw|ForsakenHarmony|kdy1|kwonoj|padmaia|sokra|wbinnssmith)$" - label: "created-by: turborepo" when: - isPRAuthorMatch: "^(gsoltis|anthonyshew|tknickman|mehulkar|chris-olszewski|NicholasLYang|arlyon|Zertsov)$" + isPRAuthorMatch: "^(gsoltis|anthonyshew|tknickman|mehulkar|chris-olszewski|NicholasLYang|arlyon|Zertsov|paulogdm|codybrouwers)$" + + # needs: triage when not any of the turbopack or turborepo team + - label: "needs: triage" + when: + isNotPRAuthorMatch: "^(bgw|ForsakenHarmony|kdy1|kwonoj|padmaia|sokra|wbinnssmith|gsoltis|anthonyshew|tknickman|mehulkar|chris-olszewski|NicholasLYang|arlyon|Zertsov|paulogdm|codybrouwers)$" # areas - label: "area: ci" diff --git a/.github/workflows/bench-turborepo.yml b/.github/workflows/bench-turborepo.yml index 14a9a80bc02e4..5fa0f55528d45 100644 --- a/.github/workflows/bench-turborepo.yml +++ b/.github/workflows/bench-turborepo.yml @@ -56,7 +56,7 @@ jobs: - name: ubuntu runner: ubuntu-latest - name: macos - runner: macos-12 + runner: macos-latest - name: windows runner: windows-latest diff --git a/.github/workflows/test-turbopack-rust-bench-test.yml b/.github/workflows/test-turbopack-rust-bench-test.yml index f6cb6001024d2..779dd363fff89 100644 --- a/.github/workflows/test-turbopack-rust-bench-test.yml +++ b/.github/workflows/test-turbopack-rust-bench-test.yml @@ -32,6 +32,7 @@ jobs: uses: ./.github/actions/setup-rust with: save-cache: true + github-token: "${{ secrets.GITHUB_TOKEN }}" - name: Setup Node.js uses: ./.github/actions/setup-node diff --git a/.github/workflows/turbopack-test.yml b/.github/workflows/turbopack-test.yml index 425128f6f8db8..b5313e8d62acc 100644 --- a/.github/workflows/turbopack-test.yml +++ b/.github/workflows/turbopack-test.yml @@ -194,6 +194,7 @@ jobs: uses: ./.github/actions/setup-rust with: targets: wasm32-unknown-unknown,wasm32-wasip1-threads + github-token: "${{ secrets.GITHUB_TOKEN }}" - name: Run cargo check release run: | diff --git a/.github/workflows/turborepo-library-release.yml b/.github/workflows/turborepo-library-release.yml index ce64ae61f4afd..04008fc2dd047 100644 --- a/.github/workflows/turborepo-library-release.yml +++ b/.github/workflows/turborepo-library-release.yml @@ -17,9 +17,9 @@ jobs: fail-fast: false matrix: settings: - - host: macos-12 + - host: macos-latest target: "aarch64-apple-darwin" - - host: macos-12 + - host: macos-latest target: "x86_64-apple-darwin" - host: ubuntu-latest @@ -45,24 +45,30 @@ jobs: target: "x86_64-unknown-linux-musl" container: ghcr.io/napi-rs/napi-rs/nodejs-rust:stable-2023-09-17-alpine install: | + apk update && apk upgrade apk add libc6-compat curl + echo /root/.cargo/bin >> ${GITHUB_PATH} + echo /usr/local/cargo/bin/rustup >> ${GITHUB_PATH} setup: | + export PATH=/usr/local/cargo/bin/rustup:/root/.cargo/bin:${PATH} + rustup show active-toolchain + dirname $(rustup which cargo) >> ${GITHUB_PATH} pnpm install - host: ubuntu-latest target: "aarch64-unknown-linux-musl" container: ghcr.io/napi-rs/napi-rs/nodejs-rust:stable-2023-09-17-alpine install: | + apk update && apk upgrade apk add libc6-compat curl echo /root/.cargo/bin >> ${GITHUB_PATH} echo /usr/local/cargo/bin/rustup >> ${GITHUB_PATH} echo /aarch64-linux-musl-cross/bin >> ${GITHUB_PATH} - export PATH=/aarch64-linux-musl-cross/bin:/usr/local/cargo/bin/rustup:/root/.cargo/bin:${PATH} setup: | export PATH=/aarch64-linux-musl-cross/bin:/usr/local/cargo/bin/rustup:/root/.cargo/bin:${PATH} - rustup default $(cat ./rust-toolchain)-aarch64-unknown-linux-musl + rustup show active-toolchain rustup target add aarch64-unknown-linux-musl - rustup toolchain install $(cat ./rust-toolchain) + dirname $(rustup which cargo) >> ${GITHUB_PATH} pnpm install rust_env: CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_LINKER=/aarch64-linux-musl-cross/bin/aarch64-linux-musl-gcc RUSTFLAGS="-Ctarget-feature=-crt-static" @@ -103,7 +109,10 @@ jobs: if: ${{ matrix.settings.setup }} - name: Build native library + # For some reason PATH modifications from Setup toolchain aren't populated + # when using the nodejs-rust alpine container. run: | + export PATH=/usr/local/cargo/bin/rustup:/root/.cargo/bin:${PATH} cd packages/turbo-repository ${{ matrix.settings.rust_env }} pnpm build:release --target=${{ matrix.settings.target }} diff --git a/.github/workflows/turborepo-native-lib-test.yml b/.github/workflows/turborepo-native-lib-test.yml index 95a323e7cacfd..453db792e6fee 100644 --- a/.github/workflows/turborepo-native-lib-test.yml +++ b/.github/workflows/turborepo-native-lib-test.yml @@ -25,7 +25,7 @@ jobs: - "x64" - "metal" - name: macos - runner: macos-12 + runner: macos-latest env: TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }} TURBO_TEAM: ${{ vars.TURBO_TEAM }} diff --git a/.github/workflows/turborepo-release.yml b/.github/workflows/turborepo-release.yml index bfbcab003be0d..1f7e39ae7b2a9 100644 --- a/.github/workflows/turborepo-release.yml +++ b/.github/workflows/turborepo-release.yml @@ -106,16 +106,16 @@ jobs: fail-fast: false matrix: settings: - - host: macos-12 + - host: macos-latest target: "x86_64-apple-darwin" container-options: "--rm" - - host: macos-12 + - host: macos-latest target: "aarch64-apple-darwin" container-options: "--rm" - host: ubuntu-latest container: ubuntu:xenial container-options: "--platform=linux/amd64 --rm" - container-setup: "apt-get update && apt-get install -y curl musl-tools sudo" + container-setup: "apt-get update && apt-get install -y curl musl-tools sudo unzip" target: "x86_64-unknown-linux-musl" setup: "apt-get install -y build-essential clang-5.0 lldb-5.0 llvm-5.0-dev libclang-5.0-dev" - host: ubuntu-latest @@ -144,8 +144,9 @@ jobs: run: ${{ matrix.settings.container-setup }} - name: Setup Protoc - uses: arduino/setup-protoc@v1.2.0 + uses: arduino/setup-protoc@v2.1.0 with: + version: "26.x" repo-token: ${{ secrets.GITHUB_TOKEN }} - name: Setup capnproto diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d6f4b13dcd961..ea423f2217251 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -29,6 +29,10 @@ Thanks for your interest in contributing to Turbo! - [Rust](https://www.rust-lang.org/tools/install) - [cargo-groups](https://github.com/nicholaslyang/cargo-groups) (used to group crates into Turborepo-specific ones and Turbopack-specific ones) +### Linux Dependencies + +- LLD (LLVM Linker), as it's not installed by default on many Linux distributions (e.g. `apt install lld`). + ## Contributing to Turborepo ### Building Turborepo diff --git a/Cargo.lock b/Cargo.lock index e7927028539d9..032c44d65f512 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -35,7 +35,7 @@ checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" dependencies = [ "getrandom", "once_cell", - "version_check 0.9.4", + "version_check", ] [[package]] @@ -44,11 +44,11 @@ version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d713b3834d76b85304d4d525563c1276e2e30dc97cc67bfb4585a4a29fc2c89f" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "getrandom", "once_cell", "serde", - "version_check 0.9.4", + "version_check", "zerocopy", ] @@ -103,7 +103,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" dependencies = [ - "winapi 0.3.9", + "winapi", ] [[package]] @@ -244,9 +244,9 @@ dependencies = [ [[package]] name = "ast_node" -version = "0.9.7" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e521452c6bce47ee5a5461c5e5d707212907826de14124962c58fcaf463115e" +checksum = "2ab31376d309dd3bfc9cfb3c11c93ce0e0741bbe0354b20e7f8c60b044730b79" dependencies = [ "proc-macro2", "quote", @@ -314,11 +314,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" dependencies = [ "async-lock", - "autocfg 1.1.0", - "cfg-if 1.0.0", + "autocfg", + "cfg-if", "concurrent-queue", "futures-lite", - "log 0.4.20", + "log", "parking", "polling", "rustix 0.37.23", @@ -359,9 +359,9 @@ checksum = "6381ead98388605d0d9ff86371043b5aa922a3905824244de40dc263a14fcba4" dependencies = [ "async-io", "async-lock", - "autocfg 1.1.0", + "autocfg", "blocking", - "cfg-if 1.0.0", + "cfg-if", "event-listener", "futures-lite", "libc", @@ -391,14 +391,14 @@ dependencies = [ "async-io", "async-lock", "async-process", - "crossbeam-utils 0.8.16", + "crossbeam-utils", "futures-channel", "futures-core", "futures-io", "futures-lite", "gloo-timers", "kv-log-macro", - "log 0.4.20", + "log", "memchr", "once_cell", "pin-project-lite", @@ -454,10 +454,10 @@ checksum = "8e6acf7e4a267eecbb127ed696bb2d50572c22ba7f586a646321e1798d8336a1" dependencies = [ "futures-io", "futures-util", - "log 0.4.20", + "log", "pin-project-lite", "tokio", - "tungstenite", + "tungstenite 0.18.0", ] [[package]] @@ -483,7 +483,7 @@ checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ "hermit-abi 0.1.19", "libc", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -491,7 +491,7 @@ name = "auto-hash-map" version = "0.1.0" dependencies = [ "serde", - "smallvec 1.13.1", + "smallvec", ] [[package]] @@ -505,15 +505,6 @@ dependencies = [ "syn 2.0.58", ] -[[package]] -name = "autocfg" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dde43e75fd43e8a1bf86103336bc699aa8d17ad1be60c76c0bdfd4828e19b78" -dependencies = [ - "autocfg 1.1.0", -] - [[package]] name = "autocfg" version = "1.1.0" @@ -544,7 +535,7 @@ dependencies = [ "anyhow", "arrayvec 0.7.4", "itertools 0.10.5", - "log 0.4.20", + "log", "nom", "num-rational", "serde", @@ -569,16 +560,16 @@ dependencies = [ "async-trait", "axum-core", "bitflags 1.3.2", - "bytes 1.5.0", + "bytes", "futures-util", - "http", + "http 0.2.11", "http-body", - "hyper 0.14.28", + "hyper", "itoa", "matchit", "memchr", - "mime 0.3.17", - "percent-encoding 2.3.0", + "mime", + "percent-encoding", "pin-project-lite", "rustversion", "serde", @@ -599,11 +590,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2f958c80c248b34b9a877a643811be8dbca03ca5ba827f2b63baf3a81e5fc4e" dependencies = [ "async-trait", - "bytes 1.5.0", + "bytes", "futures-util", - "http", + "http 0.2.11", "http-body", - "mime 0.3.17", + "mime", "rustversion", "tower-layer", "tower-service", @@ -615,11 +606,11 @@ version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bace45b270e36e3c27a190c65883de6dfc9f1d18c829907c127464815dc67b24" dependencies = [ - "bytes 1.5.0", + "bytes", "futures-util", - "http", + "http 0.2.11", "http-body", - "hyper 0.14.28", + "hyper", "tokio", "tower-service", ] @@ -632,7 +623,7 @@ checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12" dependencies = [ "addr2line", "cc", - "cfg-if 1.0.0", + "cfg-if", "libc", "miniz_oxide", "object", @@ -660,25 +651,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d27c3610c36aee21ce8ac510e6224498de4228ad772a171ed65643a24693a5a8" -[[package]] -name = "base64" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643" -dependencies = [ - "byteorder", - "safemem", -] - -[[package]] -name = "base64" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" -dependencies = [ - "byteorder", -] - [[package]] name = "base64" version = "0.13.1" @@ -691,6 +663,12 @@ version = "0.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + [[package]] name = "base64-simd" version = "0.7.0" @@ -729,7 +707,7 @@ dependencies = [ "clang-sys", "lazy_static", "lazycell", - "log 0.4.20", + "log", "peeking_take_while", "prettyplease 0.2.4", "proc-macro2", @@ -743,9 +721,9 @@ dependencies = [ [[package]] name = "binding_macros" -version = "0.64.23" +version = "0.66.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61a30675e0f0406190035d0acdf826e65eb8b91e3d27464d83ede9570ee4ea33" +checksum = "ee3f426fc63b42e1c6e6e0974d3fa3fe08513c5b441d80fd24d0c0a54b661dfa" dependencies = [ "anyhow", "console_error_panic_hook", @@ -993,21 +971,9 @@ dependencies = [ "arrayref", "arrayvec 0.7.4", "cc", - "cfg-if 1.0.0", + "cfg-if", "constant_time_eq", - "digest 0.10.7", -] - -[[package]] -name = "block-buffer" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" -dependencies = [ - "block-padding", - "byte-tools", - "byteorder", - "generic-array 0.12.4", + "digest", ] [[package]] @@ -1016,16 +982,7 @@ version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ - "generic-array 0.14.7", -] - -[[package]] -name = "block-padding" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" -dependencies = [ - "byte-tools", + "generic-array", ] [[package]] @@ -1141,12 +1098,6 @@ version = "3.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" -[[package]] -name = "byte-tools" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" - [[package]] name = "bytecheck" version = "0.6.11" @@ -1187,16 +1138,6 @@ version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" -[[package]] -name = "bytes" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" -dependencies = [ - "byteorder", - "iovec", -] - [[package]] name = "bytes" version = "1.5.0" @@ -1245,10 +1186,10 @@ version = "8.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "031718ddb8f78aa5def78a09e90defe30151d1f6c672f937af4dd916429ed996" dependencies = [ - "semver 1.0.18", + "semver 1.0.23", "serde", "toml 0.5.11", - "url 2.4.1", + "url", ] [[package]] @@ -1268,7 +1209,7 @@ checksum = "eee4243f1f26fc7a42710e7439c149e2b10b05472f88090acce52632f231a73a" dependencies = [ "camino", "cargo-platform", - "semver 1.0.18", + "semver 1.0.23", "serde", "serde_json", "thiserror", @@ -1332,16 +1273,10 @@ version = "0.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b40ccee03b5175c18cde8f37e7d2a33bcef6f8ec8f7cc0d81090d1bb380949c9" dependencies = [ - "smallvec 1.13.1", + "smallvec", "target-lexicon", ] -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" - [[package]] name = "cfg-if" version = "1.0.0" @@ -1356,12 +1291,12 @@ checksum = "1fbef58698a487c253c55c3d17bb1efbe268d2961a2c8278e3f86fff721355fc" dependencies = [ "async-tungstenite", "base64 0.21.4", - "cfg-if 1.0.0", + "cfg-if", "chromiumoxide_cdp", "chromiumoxide_types", "dunce", "fnv", - "futures 0.3.30", + "futures", "futures-timer", "pin-project-lite", "serde", @@ -1369,7 +1304,7 @@ dependencies = [ "thiserror", "tokio", "tracing", - "url 2.4.1", + "url", "which", "winreg", ] @@ -1537,15 +1472,6 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" -[[package]] -name = "cloudabi" -version = "0.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "cmake" version = "0.1.49" @@ -1579,7 +1505,7 @@ version = "4.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35ed6e9d84f0b51a7f52daf1c7d71dd136fd7a3f41a8462b8cdb8c78d920fad4" dependencies = [ - "bytes 1.5.0", + "bytes", "memchr", ] @@ -1592,7 +1518,7 @@ dependencies = [ "async-trait", "nix 0.26.2", "tokio", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -1602,7 +1528,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f86b9c4c00838774a6d902ef931eff7470720c51d90c2e32cfe15dc304737b3f" dependencies = [ "castaway 0.2.2", - "cfg-if 1.0.0", + "cfg-if", "itoa", "ryu", "static_assertions", @@ -1614,7 +1540,7 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c278839b831783b70278b14df4d45e1beb1aad306c07bb796637de9a0e323e8e" dependencies = [ - "crossbeam-utils 0.8.16", + "crossbeam-utils", ] [[package]] @@ -1664,8 +1590,8 @@ checksum = "22a3a81dfaf6b66bce5d159eddae701e3a002f194d378cbf7be5f053c281d9be" dependencies = [ "console-api", "crossbeam-channel", - "crossbeam-utils 0.8.16", - "futures 0.3.30", + "crossbeam-utils", + "futures", "hdrhistogram", "humantime", "prost-types", @@ -1686,7 +1612,7 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "wasm-bindgen", ] @@ -1774,12 +1700,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" -[[package]] -name = "convert_case" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb4a24b1aaf0fd0ce8b45161144d6f42cd91677fd5940fd431183eb023b3a2b8" - [[package]] name = "convert_case" version = "0.6.0" @@ -1854,8 +1774,8 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "80128832c58ea9cbd041d2a759ec449224487b2c1e400453d99d244eead87a8e" dependencies = [ - "autocfg 1.1.0", - "cfg-if 1.0.0", + "autocfg", + "cfg-if", "libc", "scopeguard", "windows-sys 0.33.0", @@ -1873,7 +1793,7 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7e8227005286ec39567949b33df9896bcadfa6051bccca2488129f108ca23119" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", ] [[package]] @@ -1909,9 +1829,9 @@ dependencies = [ "cranelift-entity", "cranelift-isle", "gimli 0.26.2", - "log 0.4.20", + "log", "regalloc2", - "smallvec 1.13.1", + "smallvec", "target-lexicon", ] @@ -1940,8 +1860,8 @@ dependencies = [ "fxhash", "hashbrown 0.12.3", "indexmap 1.9.3", - "log 0.4.20", - "smallvec 1.13.1", + "log", + "smallvec", ] [[package]] @@ -1957,8 +1877,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d70abacb8cfef3dc8ff7e8836e9c1d70f7967dfdac824a4cd5e30223415aca6" dependencies = [ "cranelift-codegen", - "log 0.4.20", - "smallvec 1.13.1", + "log", + "smallvec", "target-lexicon", ] @@ -1989,7 +1909,7 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", ] [[package]] @@ -2004,7 +1924,7 @@ dependencies = [ "ciborium", "clap 3.2.23", "criterion-plot", - "futures 0.3.30", + "futures", "itertools 0.10.5", "lazy_static", "num-traits", @@ -2051,12 +1971,12 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2801af0d36612ae591caa9568261fddce32ce6e08a7275ea334a06a4ad021a2c" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "crossbeam-channel", "crossbeam-deque", "crossbeam-epoch", "crossbeam-queue", - "crossbeam-utils 0.8.16", + "crossbeam-utils", ] [[package]] @@ -2065,8 +1985,8 @@ version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" dependencies = [ - "cfg-if 1.0.0", - "crossbeam-utils 0.8.16", + "cfg-if", + "crossbeam-utils", ] [[package]] @@ -2075,9 +1995,9 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "crossbeam-epoch", - "crossbeam-utils 0.8.16", + "crossbeam-utils", ] [[package]] @@ -2086,9 +2006,9 @@ version = "0.9.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" dependencies = [ - "autocfg 1.1.0", - "cfg-if 1.0.0", - "crossbeam-utils 0.8.16", + "autocfg", + "cfg-if", + "crossbeam-utils", "memoffset 0.9.0", "scopeguard", ] @@ -2099,19 +2019,8 @@ version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add" dependencies = [ - "cfg-if 1.0.0", - "crossbeam-utils 0.8.16", -] - -[[package]] -name = "crossbeam-utils" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" -dependencies = [ - "autocfg 1.1.0", - "cfg-if 0.1.10", - "lazy_static", + "cfg-if", + "crossbeam-utils", ] [[package]] @@ -2120,7 +2029,7 @@ version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", ] [[package]] @@ -2132,11 +2041,11 @@ dependencies = [ "bitflags 1.3.2", "crossterm_winapi", "libc", - "mio 0.8.8", - "parking_lot 0.12.1", + "mio", + "parking_lot", "signal-hook", "signal-hook-mio", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -2148,11 +2057,11 @@ dependencies = [ "bitflags 1.3.2", "crossterm_winapi", "libc", - "mio 0.8.8", - "parking_lot 0.12.1", + "mio", + "parking_lot", "signal-hook", "signal-hook-mio", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -2164,11 +2073,11 @@ dependencies = [ "bitflags 2.5.0", "crossterm_winapi", "libc", - "mio 0.8.8", - "parking_lot 0.12.1", + "mio", + "parking_lot", "signal-hook", "signal-hook-mio", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -2177,7 +2086,7 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" dependencies = [ - "winapi 0.3.9", + "winapi", ] [[package]] @@ -2192,7 +2101,7 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ - "generic-array 0.14.7", + "generic-array", "typenum", ] @@ -2207,7 +2116,7 @@ dependencies = [ "itoa", "phf 0.11.2", "serde", - "smallvec 1.13.1", + "smallvec", ] [[package]] @@ -2267,7 +2176,7 @@ dependencies = [ "openssl-sys", "schannel", "socket2 0.4.9", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -2283,7 +2192,7 @@ dependencies = [ "openssl-sys", "pkg-config", "vcpkg", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -2361,11 +2270,11 @@ version = "5.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "hashbrown 0.14.3", - "lock_api 0.4.10", + "lock_api", "once_cell", - "parking_lot_core 0.9.8", + "parking_lot_core", ] [[package]] @@ -2489,22 +2398,13 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8" -[[package]] -name = "digest" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" -dependencies = [ - "generic-array 0.12.4", -] - [[package]] name = "digest" version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer 0.10.4", + "block-buffer", "crypto-common", "subtle", ] @@ -2533,7 +2433,7 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "dirs-sys-next", ] @@ -2545,7 +2445,7 @@ checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" dependencies = [ "libc", "redox_users", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -2568,7 +2468,7 @@ checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" dependencies = [ "libc", "redox_users", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -2645,7 +2545,7 @@ checksum = "439a1c2ba5611ad3ed731280541d36d2e9c4ac5e7fb818a27b604bdc5a6aa65b" dependencies = [ "lazy_static", "libc", - "winapi 0.3.9", + "winapi", "wio", ] @@ -2679,7 +2579,7 @@ version = "0.8.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", ] [[package]] @@ -2735,7 +2635,7 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a19187fea3ac7e84da7dacf48de0c45d63c6a76f9490dae389aead16c243fce3" dependencies = [ - "log 0.4.20", + "log", "regex", ] @@ -2770,12 +2670,6 @@ version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" -[[package]] -name = "fake-simd" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" - [[package]] name = "fallible-iterator" version = "0.2.0" @@ -2812,7 +2706,7 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9f0c14694cbd524c8720dd69b0e3179344f04ebb5f90f2e4a440c6ea3b2f1ee" dependencies = [ - "log 0.4.20", + "log", ] [[package]] @@ -2832,7 +2726,7 @@ checksum = "7199d965852c3bac31f779ef99cbb4537f80e952e2d6aa0ffeb30cce00f4f46e" dependencies = [ "libc", "thiserror", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -2841,7 +2735,7 @@ version = "0.2.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4029edd3e734da6fe05b6cd7bd2960760a616bd2ddd0d59a0124746d6272af0" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "libc", "redox_syscall 0.3.5", "windows-sys 0.48.0", @@ -2856,7 +2750,7 @@ dependencies = [ "cc", "lazy_static", "libc", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -2904,11 +2798,11 @@ dependencies = [ "freetype", "lazy_static", "libc", - "log 0.4.20", + "log", "pathfinder_geometry", "pathfinder_simd", "walkdir", - "winapi 0.3.9", + "winapi", "yeslogic-fontconfig-sys", ] @@ -2933,7 +2827,7 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" dependencies = [ - "percent-encoding 2.3.0", + "percent-encoding", ] [[package]] @@ -2959,9 +2853,9 @@ dependencies = [ [[package]] name = "from_variant" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a0b11eeb173ce52f84ebd943d42e58813a2ebb78a6a3ff0a243b71c5199cd7b" +checksum = "fdc9cc75639b041067353b9bce2450d6847e547276c6fbe4487d7407980e07db" dependencies = [ "proc-macro2", "swc_macros_common", @@ -2995,34 +2889,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" -[[package]] -name = "fuchsia-zircon" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" -dependencies = [ - "bitflags 1.3.2", - "fuchsia-zircon-sys", -] - -[[package]] -name = "fuchsia-zircon-sys" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" - [[package]] name = "funty" version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" -[[package]] -name = "futures" -version = "0.1.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678" - [[package]] name = "futures" version = "0.3.30" @@ -3103,7 +2975,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fde5a672a61f96552aa5ed9fd9c81c3fbdae4be9b1e205d6eaf17c83705adc0f" dependencies = [ - "futures 0.3.30", + "futures", "pin-project-lite", "tokio", ] @@ -3163,12 +3035,17 @@ dependencies = [ ] [[package]] -name = "generic-array" -version = "0.12.4" +name = "generator" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd" +checksum = "186014d53bc231d0090ef8d6f03e0920c54d85a5ed22f4f2f74315ec56cf83fb" dependencies = [ - "typenum", + "cc", + "cfg-if", + "libc", + "log", + "rustversion", + "windows 0.54.0", ] [[package]] @@ -3178,7 +3055,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", - "version_check 0.9.4", + "version_check", ] [[package]] @@ -3187,10 +3064,10 @@ version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "js-sys", "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", "wasm-bindgen", ] @@ -3240,8 +3117,8 @@ dependencies = [ "bitflags 1.3.2", "libc", "libgit2-sys", - "log 0.4.20", - "url 2.4.1", + "log", + "url", ] [[package]] @@ -3253,8 +3130,8 @@ dependencies = [ "bitflags 1.3.2", "libc", "libgit2-sys", - "log 0.4.20", - "url 2.4.1", + "log", + "url", ] [[package]] @@ -3271,7 +3148,7 @@ checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1" dependencies = [ "aho-corasick", "bstr 1.8.0", - "log 0.4.20", + "log", "regex-automata 0.4.5", "regex-syntax 0.8.2", ] @@ -3299,7 +3176,7 @@ dependencies = [ name = "globwatch" version = "0.1.0" dependencies = [ - "futures 0.3.30", + "futures", "itertools 0.10.5", "merge-streams", "notify", @@ -3339,12 +3216,12 @@ version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9" dependencies = [ - "bytes 1.5.0", + "bytes", "fnv", "futures-core", "futures-sink", "futures-util", - "http", + "http 0.2.11", "indexmap 2.2.3", "slab", "tokio", @@ -3360,11 +3237,11 @@ checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" [[package]] name = "handlebars" -version = "4.3.6" +version = "5.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "035ef95d03713f2c347a72547b7cd38cbc9af7cd51e6099fb62d586d4a6dee3a" +checksum = "d08485b96a0e6393e9e4d1b8d48cf74ad6c063cd905eb33f42c1ce3f0377539b" dependencies = [ - "log 0.4.20", + "log", "pest", "pest_derive", "serde", @@ -3478,7 +3355,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest 0.10.7", + "digest", ] [[package]] @@ -3489,7 +3366,7 @@ checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" dependencies = [ "libc", "match_cfg", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -3512,7 +3389,18 @@ version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" dependencies = [ - "bytes 1.5.0", + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +dependencies = [ + "bytes", "fnv", "itoa", ] @@ -3523,8 +3411,8 @@ version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" dependencies = [ - "bytes 1.5.0", - "http", + "bytes", + "http 0.2.11", "pin-project-lite", ] @@ -3550,21 +3438,21 @@ dependencies = [ "async-object-pool", "async-trait", "base64 0.21.4", - "crossbeam-utils 0.8.16", + "crossbeam-utils", "form_urlencoded", "futures-util", - "hyper 0.14.28", + "hyper", "isahc", "lazy_static", "levenshtein", - "log 0.4.20", + "log", "regex", "serde", "serde_json", "serde_regex", "similar", "tokio", - "url 2.4.1", + "url", ] [[package]] @@ -3589,37 +3477,18 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" -[[package]] -name = "hyper" -version = "0.10.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a0652d9a2609a968c14be1a9ea00bf4b1d64e2e1f53a1b51b6fff3a6e829273" -dependencies = [ - "base64 0.9.3", - "httparse", - "language-tags", - "log 0.3.9", - "mime 0.2.6", - "num_cpus", - "time 0.1.45", - "traitobject", - "typeable", - "unicase 1.4.2", - "url 1.7.2", -] - [[package]] name = "hyper" version = "0.14.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" dependencies = [ - "bytes 1.5.0", + "bytes", "futures-channel", "futures-core", "futures-util", "h2", - "http", + "http 0.2.11", "http-body", "httparse", "httpdate", @@ -3638,8 +3507,8 @@ version = "0.23.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1788965e61b367cd03a62950836d5cd41560c3577d90e40e0819373194d1661c" dependencies = [ - "http", - "hyper 0.14.28", + "http 0.2.11", + "hyper", "rustls 0.20.9", "tokio", "tokio-rustls", @@ -3651,7 +3520,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" dependencies = [ - "hyper 0.14.28", + "hyper", "pin-project-lite", "tokio", "tokio-io-timeout", @@ -3663,8 +3532,8 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ - "bytes 1.5.0", - "hyper 0.14.28", + "bytes", + "hyper", "native-tls", "tokio", "tokio-native-tls", @@ -3676,11 +3545,11 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "880b8b1c98a5ec2a505c7c90db6d3f6f1f480af5655d9c5b55facc9382a5a5b5" dependencies = [ - "hyper 0.14.28", + "hyper", "pin-project", "tokio", "tokio-tungstenite", - "tungstenite", + "tungstenite 0.18.0", ] [[package]] @@ -3694,7 +3563,7 @@ dependencies = [ "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "windows", + "windows 0.48.0", ] [[package]] @@ -3718,17 +3587,6 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" -[[package]] -name = "idna" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" -dependencies = [ - "matches", - "unicode-bidi", - "unicode-normalization", -] - [[package]] name = "idna" version = "0.4.0" @@ -3753,7 +3611,7 @@ checksum = "b46810df39e66e925525d6e38ce1e7f6e1d208f72dc39757880fcb66e2c58af1" dependencies = [ "crossbeam-deque", "globset", - "log 0.4.20", + "log", "memchr", "regex-automata 0.4.5", "same-file", @@ -3836,7 +3694,7 @@ version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ - "autocfg 1.1.0", + "autocfg", "hashbrown 0.12.3", "serde", ] @@ -3927,7 +3785,7 @@ version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", ] [[package]] @@ -3961,15 +3819,6 @@ dependencies = [ "libc", ] -[[package]] -name = "iovec" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" -dependencies = [ - "libc", -] - [[package]] name = "ipnet" version = "2.7.1" @@ -4013,22 +3862,22 @@ checksum = "334e04b4d781f436dc315cb1e7515bd96826426345d498149e4bde36b67f8ee9" dependencies = [ "async-channel", "castaway 0.1.2", - "crossbeam-utils 0.8.16", + "crossbeam-utils", "curl", "curl-sys", "encoding_rs", "event-listener", "futures-lite", - "http", - "log 0.4.20", - "mime 0.3.17", + "http 0.2.11", + "log", + "mime", "once_cell", "polling", "slab", "sluice", "tracing", "tracing-futures", - "url 2.4.1", + "url", "waker-fn", ] @@ -4081,10 +3930,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" dependencies = [ "cesu8", - "cfg-if 1.0.0", + "cfg-if", "combine", "jni-sys", - "log 0.4.20", + "log", "thiserror", "walkdir", "windows-sys 0.45.0", @@ -4141,16 +3990,6 @@ version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7725c320caac8c21d8228c1d055af27a995d371f78cc763073d3e068323641b5" -[[package]] -name = "kernel32-sys" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" -dependencies = [ - "winapi 0.2.8", - "winapi-build", -] - [[package]] name = "kqueue" version = "1.0.8" @@ -4177,7 +4016,7 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" dependencies = [ - "log 0.4.20", + "log", ] [[package]] @@ -4186,12 +4025,6 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf36173d4167ed999940f804952e6b08197cae5ad5d572eb4db150ce8ad5d58f" -[[package]] -name = "language-tags" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" - [[package]] name = "lazy-regex" version = "2.5.0" @@ -4355,8 +4188,8 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" dependencies = [ - "cfg-if 1.0.0", - "winapi 0.3.9", + "cfg-if", + "winapi", ] [[package]] @@ -4365,7 +4198,7 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c571b676ddfc9a8c12f1f3d3085a7b163966a8fd8098a90640953ce5f6170161" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "windows-sys 0.48.0", ] @@ -4409,17 +4242,18 @@ dependencies = [ [[package]] name = "lightningcss" -version = "1.0.0-alpha.51" +version = "1.0.0-alpha.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99d6ad516c08b24c246b339159dc2ee2144c012e8ebdf4db4bddefb8734b2b69" +checksum = "3bd5bed3814fb631bfc1e24c2be6f7e86a9837c660909acab79a38374dcb8798" dependencies = [ - "ahash 0.7.8", + "ahash 0.8.9", "bitflags 2.5.0", "const-str", "cssparser", "cssparser-color", "dashmap", "data-encoding", + "getrandom", "itertools 0.10.5", "lazy_static", "lightningcss-derive", @@ -4429,7 +4263,7 @@ dependencies = [ "pathdiff", "rayon", "serde", - "smallvec 1.13.1", + "smallvec", "static-self", ] @@ -4471,41 +4305,36 @@ version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" -[[package]] -name = "lock_api" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4da24a77a3d8a6d4862d95f72e6fdb9c09a643ecdb402d754004a557f2bec75" -dependencies = [ - "scopeguard", -] - [[package]] name = "lock_api" version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" dependencies = [ - "autocfg 1.1.0", + "autocfg", "scopeguard", ] [[package]] name = "log" -version = "0.3.9" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" dependencies = [ - "log 0.4.20", + "value-bag", ] [[package]] -name = "log" -version = "0.4.20" +name = "loom" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "419e0dc8046cb947daa77eb95ae174acfbddb7673b4151f56d1eed8e93fbfaca" dependencies = [ - "value-bag", + "cfg-if", + "generator", + "scoped-tls", + "tracing", + "tracing-subscriber", ] [[package]] @@ -4545,7 +4374,7 @@ dependencies = [ "serde", "serde_json", "serde_repr", - "url 2.4.1", + "url", ] [[package]] @@ -4568,9 +4397,9 @@ dependencies = [ [[package]] name = "markdown" -version = "1.0.0-alpha.16" +version = "1.0.0-alpha.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0f0025e8c0d89b84d6dc63e859475e40e8e82ab1a08be0a93ad5731513a508" +checksum = "21e27d6220ce21f80ce5c4201f23a37c6f1ad037c72c9d1ff215c2919605a5d6" dependencies = [ "unicode-id", ] @@ -4608,30 +4437,24 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ea1f30cedd69f0a2954655f7188c6a834246d2bcf1e315e2ac40c4b24dc9519" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "rayon", ] -[[package]] -name = "maybe-uninit" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" - [[package]] name = "md4" version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da5ac363534dce5fabf69949225e174fbf111a498bf0ff794c8ea1fba9f3dda" dependencies = [ - "digest 0.10.7", + "digest", ] [[package]] name = "mdxjs" -version = "0.1.23" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "539f014f8de0298191ec2c05cb91b8bab0530be56b268dffedac7944c9c5f36a" +checksum = "e5860860bfc09972a5d99bfb866dde39485fe397210f8a9ccf68a6c6740d687b" dependencies = [ "markdown", "serde", @@ -4668,7 +4491,7 @@ version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" dependencies = [ - "autocfg 1.1.0", + "autocfg", ] [[package]] @@ -4677,7 +4500,7 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" dependencies = [ - "autocfg 1.1.0", + "autocfg", ] [[package]] @@ -4686,7 +4509,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" dependencies = [ - "autocfg 1.1.0", + "autocfg", ] [[package]] @@ -4695,7 +4518,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" dependencies = [ - "autocfg 1.1.0", + "autocfg", ] [[package]] @@ -4800,15 +4623,6 @@ dependencies = [ "cty", ] -[[package]] -name = "mime" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba626b8a6de5da682e1caa06bdb42a335aee5a84db8e5046a3e8ab17ba0a3ae0" -dependencies = [ - "log 0.3.9", -] - [[package]] name = "mime" version = "0.3.17" @@ -4821,8 +4635,8 @@ version = "2.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" dependencies = [ - "mime 0.3.17", - "unicase 2.6.0", + "mime", + "unicase", ] [[package]] @@ -4841,25 +4655,6 @@ dependencies = [ "simd-adler32", ] -[[package]] -name = "mio" -version = "0.6.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4afd66f5b91bf2a3bc13fad0e21caedac168ca4c707504e75585648ae80e4cc4" -dependencies = [ - "cfg-if 0.1.10", - "fuchsia-zircon", - "fuchsia-zircon-sys", - "iovec", - "kernel32-sys", - "libc", - "log 0.4.20", - "miow", - "net2", - "slab", - "winapi 0.2.8", -] - [[package]] name = "mio" version = "0.8.8" @@ -4867,30 +4662,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" dependencies = [ "libc", - "log 0.4.20", - "wasi 0.11.0+wasi-snapshot-preview1", + "log", + "wasi", "windows-sys 0.48.0", ] -[[package]] -name = "miow" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebd808424166322d4a38da87083bfddd3ac4c131334ed55856112eb06d46944d" -dependencies = [ - "kernel32-sys", - "net2", - "winapi 0.2.8", - "ws2_32-sys", -] - [[package]] name = "modularize_imports" -version = "0.68.9" +version = "0.68.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ef94a126a88f5ba86c3b2e366fef393d27992693df15d44ff56de2f4e7d1344" +checksum = "440dfda6d4b4cfa76c0b12b564c9b8d643b5c2bc8a63ed5dfc2a46cf1c68ac61" dependencies = [ - "convert_case 0.5.0", + "convert_case 0.6.0", "handlebars", "once_cell", "regex", @@ -4948,7 +4731,7 @@ version = "2.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7622f0dbe0968af2dacdd64870eee6dee94f93c989c841f1ad8f300cf1abd514" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "convert_case 0.6.0", "napi-derive-backend", "proc-macro2", @@ -4967,7 +4750,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "semver 1.0.18", + "semver 1.0.23", "syn 2.0.58", ] @@ -4997,7 +4780,7 @@ checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" dependencies = [ "lazy_static", "libc", - "log 0.4.20", + "log", "openssl", "openssl-probe", "openssl-sys", @@ -5013,17 +4796,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" -[[package]] -name = "net2" -version = "0.2.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d0df99cfcd2530b2e694f6e17e7f37b8e26bb23983ac530c0c97408837c631" -dependencies = [ - "cfg-if 0.1.10", - "libc", - "winapi 0.3.9", -] - [[package]] name = "new_debug_unreachable" version = "1.0.4" @@ -5045,7 +4817,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43" dependencies = [ - "smallvec 1.13.1", + "smallvec", ] [[package]] @@ -5054,9 +4826,9 @@ version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f346ff70e7dbfd675fe90590b92d59ef2de15a8779ae305ebcbfd3f0caf59be4" dependencies = [ - "autocfg 1.1.0", + "autocfg", "bitflags 1.3.2", - "cfg-if 1.0.0", + "cfg-if", "libc", "memoffset 0.6.5", "pin-utils", @@ -5069,7 +4841,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a" dependencies = [ "bitflags 1.3.2", - "cfg-if 1.0.0", + "cfg-if", "libc", "memoffset 0.7.1", "pin-utils", @@ -5138,7 +4910,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a9da8c9922c35a1033d76f7272dfc2e7ee20392083d75aeea6ced23c6266578" dependencies = [ - "winapi 0.3.9", + "winapi", ] [[package]] @@ -5154,8 +4926,8 @@ dependencies = [ "inotify", "kqueue", "libc", - "log 0.4.20", - "mio 0.8.8", + "log", + "mio", "walkdir", "windows-sys 0.48.0", ] @@ -5168,9 +4940,9 @@ checksum = "49f5dab59c348b9b50cf7f261960a20e389feb2713636399cd9082cd4b536154" dependencies = [ "crossbeam-channel", "file-id", - "log 0.4.20", + "log", "notify", - "parking_lot 0.12.1", + "parking_lot", "walkdir", ] @@ -5180,7 +4952,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4" dependencies = [ - "winapi 0.3.9", + "winapi", ] [[package]] @@ -5190,7 +4962,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" dependencies = [ "overload", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -5199,7 +4971,7 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" dependencies = [ - "autocfg 1.1.0", + "autocfg", "num-integer", "num-traits", "serde", @@ -5243,7 +5015,7 @@ version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" dependencies = [ - "autocfg 1.1.0", + "autocfg", "num-traits", ] @@ -5253,7 +5025,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" dependencies = [ - "autocfg 1.1.0", + "autocfg", "num-bigint", "num-integer", "num-traits", @@ -5265,7 +5037,7 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" dependencies = [ - "autocfg 1.1.0", + "autocfg", ] [[package]] @@ -5335,12 +5107,6 @@ version = "11.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" -[[package]] -name = "opaque-debug" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" - [[package]] name = "openssl" version = "0.10.47" @@ -5348,7 +5114,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d8b277f87dacc05a6b709965d1cbafac4649d6ce9f3ce9ceb88508b5666dfec9" dependencies = [ "bitflags 1.3.2", - "cfg-if 1.0.0", + "cfg-if", "foreign-types", "libc", "once_cell", @@ -5379,7 +5145,7 @@ version = "0.9.82" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a95792af3c4e0153c3914df2261bedd30a98476f94dc892b67dfe1d89d433a04" dependencies = [ - "autocfg 1.1.0", + "autocfg", "cc", "libc", "pkg-config", @@ -5408,9 +5174,9 @@ version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "006e42d5b888366f1880eda20371fedde764ed2213dc8496f49622fa0c99cd5e" dependencies = [ - "log 0.4.20", + "log", "serde", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -5480,12 +5246,12 @@ dependencies = [ "bitflags 2.5.0", "cssparser", "fxhash", - "log 0.4.20", + "log", "phf 0.10.1", "phf_codegen", "precomputed-hash", "serde", - "smallvec 1.13.1", + "smallvec", "static-self", ] @@ -5509,40 +5275,14 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72" -[[package]] -name = "parking_lot" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252" -dependencies = [ - "lock_api 0.3.4", - "parking_lot_core 0.6.3", - "rustc_version 0.2.3", -] - [[package]] name = "parking_lot" version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ - "lock_api 0.4.10", - "parking_lot_core 0.9.8", -] - -[[package]] -name = "parking_lot_core" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66b810a62be75176a80873726630147a5ca780cd33921e0b5709033e66b0a" -dependencies = [ - "cfg-if 0.1.10", - "cloudabi", - "libc", - "redox_syscall 0.1.57", - "rustc_version 0.2.3", - "smallvec 0.6.14", - "winapi 0.3.9", + "lock_api", + "parking_lot_core", ] [[package]] @@ -5551,10 +5291,10 @@ version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "libc", "redox_syscall 0.3.5", - "smallvec 1.13.1", + "smallvec", "windows-targets 0.48.1", ] @@ -5594,7 +5334,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b7e7b4ea703700ce73ebf128e1450eb69c3a8329199ffbfb9b2a0418e5ad3" dependencies = [ - "log 0.4.20", + "log", "pathfinder_simd", ] @@ -5621,12 +5361,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" -[[package]] -name = "percent-encoding" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" - [[package]] name = "percent-encoding" version = "2.3.0" @@ -5773,7 +5507,7 @@ name = "pidlock" version = "0.1.4" dependencies = [ "libc", - "log 0.4.20", + "log", "rand 0.8.5", "tempdir", "thiserror", @@ -5900,12 +5634,12 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7e1f879b2998099c2d69ab9605d145d5b661195627eccc680002c4918a7fb6fa" dependencies = [ - "autocfg 1.1.0", + "autocfg", "bitflags 1.3.2", - "cfg-if 1.0.0", + "cfg-if", "concurrent-queue", "libc", - "log 0.4.20", + "log", "pin-project-lite", "windows-sys 0.45.0", ] @@ -5943,12 +5677,12 @@ dependencies = [ "filedescriptor", "lazy_static", "libc", - "log 0.4.20", + "log", "nix 0.25.1", "serial", "shared_library", "shell-words", - "winapi 0.3.9", + "winapi", "winreg", ] @@ -5985,18 +5719,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "978385d59daf9269189d052ca8a84c1acfd0715c0599a5d5188d4acc078ca46a" dependencies = [ "backtrace", - "cfg-if 1.0.0", + "cfg-if", "findshlibs", "libc", - "log 0.4.20", + "log", "nix 0.26.2", "once_cell", - "parking_lot 0.12.1", + "parking_lot", "prost 0.11.8", "prost-build", "prost-derive 0.11.8", "sha2", - "smallvec 1.13.1", + "smallvec", "symbolic-demangle", "tempfile", "thiserror", @@ -6044,9 +5778,9 @@ dependencies = [ [[package]] name = "preset_env_base" -version = "0.4.11" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d99dc6ba4753f07bfbc4dbf3137618d31af2611fcaced7237647075ca687eaa" +checksum = "08ccd15679953ae0d5fa716af78b58c0bfdc69a0534bfe9ea423abd1eaaf527b" dependencies = [ "ahash 0.8.9", "anyhow", @@ -6054,7 +5788,7 @@ dependencies = [ "dashmap", "from_variant", "once_cell", - "semver 1.0.18", + "semver 1.0.23", "serde", "st-map", "tracing", @@ -6096,7 +5830,7 @@ version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ca9c6be70d989d21a136eb86c2d83e4b328447fac4a88dace2143c179c86267" dependencies = [ - "autocfg 1.1.0", + "autocfg", "indexmap 1.9.3", ] @@ -6120,7 +5854,7 @@ dependencies = [ "proc-macro2", "quote", "syn 1.0.109", - "version_check 0.9.4", + "version_check", ] [[package]] @@ -6131,7 +5865,7 @@ checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" dependencies = [ "proc-macro2", "quote", - "version_check 0.9.4", + "version_check", ] [[package]] @@ -6149,7 +5883,7 @@ version = "0.11.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e48e50df39172a3e7eb17e14642445da64996989bc212b583015435d39a58537" dependencies = [ - "bytes 1.5.0", + "bytes", "prost-derive 0.11.8", ] @@ -6159,7 +5893,7 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "146c289cda302b98a28d40c8b3b90498d6e526dd24ac2ecea73e4e491685b94a" dependencies = [ - "bytes 1.5.0", + "bytes", "prost-derive 0.12.3", ] @@ -6169,11 +5903,11 @@ version = "0.11.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c828f93f5ca4826f97fedcbd3f9a536c16b12cff3dbbb4a007f932bbad95b12" dependencies = [ - "bytes 1.5.0", + "bytes", "heck 0.4.1", "itertools 0.10.5", "lazy_static", - "log 0.4.20", + "log", "multimap", "petgraph", "prettyplease 0.1.25", @@ -6257,7 +5991,7 @@ checksum = "ffade02495f22453cd593159ea2f59827aae7f53fa8323f756799b670881dcf8" dependencies = [ "bitflags 1.3.2", "memchr", - "unicase 2.6.0", + "unicase", ] [[package]] @@ -6273,7 +6007,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "588f6378e4dd99458b60ec275b4477add41ce4fa9f64dcba6f15adccb19b50d6" dependencies = [ "env_logger", - "log 0.4.20", + "log", "rand 0.8.5", ] @@ -6318,26 +6052,7 @@ dependencies = [ "libc", "rand_core 0.3.1", "rdrand", - "winapi 0.3.9", -] - -[[package]] -name = "rand" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" -dependencies = [ - "autocfg 0.1.8", - "libc", - "rand_chacha 0.1.1", - "rand_core 0.4.2", - "rand_hc", - "rand_isaac", - "rand_jitter", - "rand_os", - "rand_pcg", - "rand_xorshift", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -6347,20 +6062,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha 0.3.1", + "rand_chacha", "rand_core 0.6.4", ] -[[package]] -name = "rand_chacha" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" -dependencies = [ - "autocfg 0.1.8", - "rand_core 0.3.1", -] - [[package]] name = "rand_chacha" version = "0.3.1" @@ -6368,93 +6073,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_core" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" -dependencies = [ - "rand_core 0.4.2", -] - -[[package]] -name = "rand_core" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom", -] - -[[package]] -name = "rand_hc" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" -dependencies = [ - "rand_core 0.3.1", -] - -[[package]] -name = "rand_isaac" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" -dependencies = [ - "rand_core 0.3.1", -] - -[[package]] -name = "rand_jitter" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" -dependencies = [ - "libc", - "rand_core 0.4.2", - "winapi 0.3.9", + "rand_core 0.6.4", ] [[package]] -name = "rand_os" -version = "0.1.3" +name = "rand_core" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" +checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" dependencies = [ - "cloudabi", - "fuchsia-cprng", - "libc", "rand_core 0.4.2", - "rdrand", - "winapi 0.3.9", ] [[package]] -name = "rand_pcg" -version = "0.1.2" +name = "rand_core" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" -dependencies = [ - "autocfg 0.1.8", - "rand_core 0.4.2", -] +checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" [[package]] -name = "rand_xorshift" -version = "0.1.1" +name = "rand_core" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "rand_core 0.3.1", + "getrandom", ] [[package]] @@ -6491,7 +6134,7 @@ dependencies = [ "bitstream-io", "built", "cc", - "cfg-if 1.0.0", + "cfg-if", "clap 4.5.2", "clap_complete", "console", @@ -6502,7 +6145,7 @@ dependencies = [ "ivf", "libc", "libfuzzer-sys", - "log 0.4.20", + "log", "maybe-rayon", "nasm-rs", "new_debug_unreachable", @@ -6513,7 +6156,7 @@ dependencies = [ "once_cell", "paste", "rand 0.8.5", - "rand_chacha 0.3.1", + "rand_chacha", "rust_hawktracer", "rustc_version 0.4.0", "scan_fmt", @@ -6565,7 +6208,7 @@ checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" dependencies = [ "crossbeam-channel", "crossbeam-deque", - "crossbeam-utils 0.8.16", + "crossbeam-utils", "num_cpus", ] @@ -6578,12 +6221,6 @@ dependencies = [ "rand_core 0.3.1", ] -[[package]] -name = "redox_syscall" -version = "0.1.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" - [[package]] name = "redox_syscall" version = "0.2.16" @@ -6640,21 +6277,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "300d4fbfb40c1c66a78ba3ddd41c1110247cf52f97b87d0f2fc9209bd49b030c" dependencies = [ "fxhash", - "log 0.4.20", + "log", "slice-group-by", - "smallvec 1.13.1", + "smallvec", ] [[package]] name = "regex" -version = "1.9.5" +version = "1.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47" +checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.3.8", - "regex-syntax 0.7.5", + "regex-automata 0.4.5", + "regex-syntax 0.8.2", ] [[package]] @@ -6666,17 +6303,6 @@ dependencies = [ "regex-syntax 0.6.29", ] -[[package]] -name = "regex-automata" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax 0.7.5", -] - [[package]] name = "regex-automata" version = "0.4.5" @@ -6694,12 +6320,6 @@ version = "0.6.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" -[[package]] -name = "regex-syntax" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" - [[package]] name = "regex-syntax" version = "0.8.2" @@ -6715,7 +6335,7 @@ dependencies = [ "bitflags 1.3.2", "libc", "mach", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -6730,7 +6350,7 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" dependencies = [ - "winapi 0.3.9", + "winapi", ] [[package]] @@ -6755,23 +6375,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13293b639a097af28fc8a90f22add145a9c954e49d77da06263d58cf44d5fb91" dependencies = [ "base64 0.21.4", - "bytes 1.5.0", + "bytes", "encoding_rs", "futures-core", "futures-util", "h2", - "http", + "http 0.2.11", "http-body", - "hyper 0.14.28", + "hyper", "hyper-rustls", "hyper-tls", "ipnet", "js-sys", - "log 0.4.20", - "mime 0.3.17", + "log", + "mime", "native-tls", "once_cell", - "percent-encoding 2.3.0", + "percent-encoding", "pin-project-lite", "rustls 0.20.9", "rustls-native-certs", @@ -6783,7 +6403,7 @@ dependencies = [ "tokio-native-tls", "tokio-rustls", "tower-service", - "url 2.4.1", + "url", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", @@ -6812,7 +6432,7 @@ dependencies = [ "spin 0.5.2", "untrusted 0.7.1", "web-sys", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -6837,7 +6457,7 @@ checksum = "5cba464629b3394fc4dbc6f940ff8f5b4ff5c7aef40f29166fd4ad12acbc99c0" dependencies = [ "bitvec", "bytecheck", - "bytes 1.5.0", + "bytes", "hashbrown 0.12.3", "indexmap 1.9.3", "ptr_meta", @@ -6865,7 +6485,7 @@ version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b07f2d176c472198ec1e6551dc7da28f1c089652f66a7b722676c2238ebc0edf" dependencies = [ - "futures 0.3.30", + "futures", "futures-timer", "rstest_macros", "rustc_version 0.4.0", @@ -6877,7 +6497,7 @@ version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7229b505ae0706e64f37ffc54a9c163e11022a6636d58fe1f3f52018257ff9f7" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "proc-macro2", "quote", "rustc_version 0.4.0", @@ -6903,7 +6523,7 @@ version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e0698206bcb8882bf2a9ecb4c1e7785db57ff052297085a6efd4fe42302068a" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "ordered-multimap", ] @@ -6956,7 +6576,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.18", + "semver 1.0.23", ] [[package]] @@ -7002,7 +6622,7 @@ version = "0.20.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b80e3dec595989ea8510028f30c408a4630db12c9cbb8de34203b89d6577e99" dependencies = [ - "log 0.4.20", + "log", "ring 0.16.20", "sct", "webpki", @@ -7014,7 +6634,7 @@ version = "0.21.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" dependencies = [ - "log 0.4.20", + "log", "ring 0.17.7", "rustls-webpki", "sct", @@ -7064,7 +6684,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ed36cdb20de66d89a17ea04b8883fc7a386f2cf877aaedca5005583ce4876ff" dependencies = [ "crossbeam-channel", - "futures 0.3.30", + "futures", "futures-channel", "futures-executor", "num_cpus", @@ -7082,12 +6702,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4950d85bc52415f8432144c97c4791bd0c4f7954de32a7270ee9cccd3c22b12b" -[[package]] -name = "safemem" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072" - [[package]] name = "same-file" version = "1.0.6" @@ -7204,9 +6818,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.18" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" dependencies = [ "serde", ] @@ -7219,9 +6833,9 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.197" +version = "1.0.201" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +checksum = "780f1cebed1629e4753a1a38a3c72d30b97ec044f0aef68cb26650a3c5cf363c" dependencies = [ "serde_derive", ] @@ -7258,9 +6872,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.197" +version = "1.0.201" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +checksum = "c5e405930b9796f1c00bee880d03fc7e0bb4b9a11afc776885ffe84320da2865" dependencies = [ "proc-macro2", "quote", @@ -7305,7 +6919,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c679fa27b429f2bb57fd4710257e643e86c966e716037259f8baa33de594a1b6" dependencies = [ - "percent-encoding 2.3.0", + "percent-encoding", "serde", "thiserror", ] @@ -7374,7 +6988,7 @@ dependencies = [ "serde", "serde_json", "serde_with_macros", - "time 0.3.30", + "time", ] [[package]] @@ -7456,27 +7070,15 @@ dependencies = [ "serial-core", ] -[[package]] -name = "sha-1" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df" -dependencies = [ - "block-buffer 0.7.3", - "digest 0.8.1", - "fake-simd", - "opaque-debug", -] - [[package]] name = "sha-1" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "028f48d513f9678cda28f6e4064755b3fbb2af6acd672f2c209b62323f7aea0f" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "cpufeatures", - "digest 0.10.7", + "digest", ] [[package]] @@ -7485,9 +7087,9 @@ version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "cpufeatures", - "digest 0.10.7", + "digest", ] [[package]] @@ -7496,9 +7098,9 @@ version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "cpufeatures", - "digest 0.10.7", + "digest", ] [[package]] @@ -7516,7 +7118,7 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6c99835bad52957e7aa241d3975ed17c1e5f8c92026377d117a606f36b84b16" dependencies = [ - "bytes 1.5.0", + "bytes", "memmap2 0.6.2", ] @@ -7527,7 +7129,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b0d94659ad3c2137fef23ae75b03d5241d633f8acded53d672decfa0e6e0caef" dependencies = [ "libc", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -7569,7 +7171,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af" dependencies = [ "libc", - "mio 0.8.8", + "mio", "signal-hook", ] @@ -7649,7 +7251,7 @@ version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" dependencies = [ - "autocfg 1.1.0", + "autocfg", ] [[package]] @@ -7669,15 +7271,6 @@ dependencies = [ "futures-io", ] -[[package]] -name = "smallvec" -version = "0.6.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97fcaeba89edba30f044a10c6a3cc39df9c3f17d7cd829dd1446cab35f890e0" -dependencies = [ - "maybe-uninit", -] - [[package]] name = "smallvec" version = "1.13.1" @@ -7693,9 +7286,9 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fb72c633efbaa2dd666986505016c32c3044395ceaf881518399d2f4127ee29" dependencies = [ - "autocfg 1.1.0", + "autocfg", "static_assertions", - "version_check 0.9.4", + "version_check", ] [[package]] @@ -7711,7 +7304,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" dependencies = [ "libc", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -7740,7 +7333,7 @@ dependencies = [ "serde", "serde_json", "unicode-id-start", - "url 2.4.1", + "url", ] [[package]] @@ -7755,7 +7348,7 @@ version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" dependencies = [ - "lock_api 0.4.10", + "lock_api", ] [[package]] @@ -7791,10 +7384,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c886bd4480155fd3ef527d45e9ac8dd7118a898a46530b7b94c3e21866259fce" dependencies = [ "cc", - "cfg-if 1.0.0", + "cfg-if", "libc", "psm", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -7815,7 +7408,7 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "253e76c8c993a7b1b201b0539228b334582153cd4364292822d2c30776d469c7" dependencies = [ - "smallvec 1.13.1", + "smallvec", "static-self-derive", ] @@ -7843,7 +7436,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af91f480ee899ab2d9f8435bfdfc14d08a5754bd9d3fef1f1a1c23336aad6c8b" dependencies = [ "async-channel", - "cfg-if 1.0.0", + "cfg-if", "futures-core", "pin-project-lite", ] @@ -7862,7 +7455,7 @@ checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" dependencies = [ "new_debug_unreachable", "once_cell", - "parking_lot 0.12.1", + "parking_lot", "phf_shared 0.10.0", "precomputed-hash", "serde", @@ -7882,9 +7475,9 @@ dependencies = [ [[package]] name = "string_enum" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6960defec35d15d58331ffb8a315d551634f757fe139c7b3d6063cae88ec90f6" +checksum = "05e383308aebc257e7d7920224fa055c632478d92744eca77f99be8fa1545b90" dependencies = [ "proc-macro2", "quote", @@ -7957,9 +7550,9 @@ dependencies = [ [[package]] name = "styled_components" -version = "0.96.8" +version = "0.96.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27f13af1b2e9b55614b681c785ddcf96e059076be58393c1055b795c8283a956" +checksum = "2d7e14a22b6bf299ed8c2072e719c27324be5060a39b2bd70e62ad2a9505fe71" dependencies = [ "Inflector", "once_cell", @@ -7975,9 +7568,9 @@ dependencies = [ [[package]] name = "styled_jsx" -version = "0.73.13" +version = "0.73.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e6eeab19721dd473f4b9c3c17f45aec015bc8bf626ab238ecd781cda90c9ddf" +checksum = "441654f465db08fc2c3c36c598c89e8d27fb445d4c97263fb701b07029e9755b" dependencies = [ "anyhow", "lightningcss", @@ -8073,14 +7666,14 @@ dependencies = [ "byteorder", "getrandom", "serde", - "time 0.3.30", + "time", ] [[package]] name = "swc" -version = "0.273.26" +version = "0.275.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b71ac791abe45ebdbf3d547595f9dc6406d3a294d23c22c8edd0ad9bb040d0f" +checksum = "2ac38cd938ce20693b58b26a5d1926a46074db09cf90a251d83cf17cdaea6031" dependencies = [ "anyhow", "base64 0.21.4", @@ -8092,7 +7685,7 @@ dependencies = [ "napi", "napi-derive", "once_cell", - "parking_lot 0.12.1", + "parking_lot", "pathdiff", "regex", "rustc-hash", @@ -8126,7 +7719,7 @@ dependencies = [ "swc_visit", "tokio", "tracing", - "url 2.4.1", + "url", ] [[package]] @@ -8156,9 +7749,9 @@ dependencies = [ [[package]] name = "swc_bundler" -version = "0.225.19" +version = "0.227.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8dda466636577e45b76ff019d040ba5f7973228cb821734460c636350ff4f3ae" +checksum = "d1a212bd08b1121c7204a04407ea055779fc00cf80024fc666dd97b00749cf87" dependencies = [ "anyhow", "crc", @@ -8166,7 +7759,7 @@ dependencies = [ "indexmap 2.2.3", "is-macro", "once_cell", - "parking_lot 0.12.1", + "parking_lot", "petgraph", "radix_fmt", "rayon", @@ -8202,9 +7795,9 @@ dependencies = [ [[package]] name = "swc_common" -version = "0.33.24" +version = "0.33.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a6a61c748b650cc498748f54b3bf86ba478b5f9f590abcf62bc939e1093ef99" +checksum = "a2f9706038906e66f3919028f9f7a37f3ed552f1b85578e93f4468742e2da438" dependencies = [ "ahash 0.8.9", "anyhow", @@ -8212,13 +7805,13 @@ dependencies = [ "atty", "better_scoped_tls", "bytecheck", - "cfg-if 1.0.0", + "cfg-if", "either", "from_variant", "new_debug_unreachable", "num-bigint", "once_cell", - "parking_lot 0.12.1", + "parking_lot", "rkyv", "rustc-hash", "serde", @@ -8230,14 +7823,14 @@ dependencies = [ "termcolor", "tracing", "unicode-width", - "url 2.4.1", + "url", ] [[package]] name = "swc_compiler_base" -version = "0.7.20" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d7a0a78d52886c01786246fad54aa614cc145154d18607ddda72a180d1cb56c" +checksum = "754058388d4f51df61f9aced73dfca96d81fed1c0a46583dc7b3da07688af80d" dependencies = [ "anyhow", "base64 0.21.4", @@ -8260,9 +7853,9 @@ dependencies = [ [[package]] name = "swc_config" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ada712ac5e28a301683c8af957e8a56deca675cbc376473dd207a527b989efb5" +checksum = "7be1a689e146be1eae53139482cb061dcf0fa01dff296bbe7b96fff92d8e2936" dependencies = [ "anyhow", "indexmap 2.2.3", @@ -8275,9 +7868,9 @@ dependencies = [ [[package]] name = "swc_config_macro" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b2574f75082322a27d990116cd2a24de52945fc94172b24ca0b3e9e2a6ceb6b" +checksum = "7c5f56139042c1a95b54f5ca48baa0e0172d369bcc9d3d473dad1de36bae8399" dependencies = [ "proc-macro2", "quote", @@ -8287,9 +7880,9 @@ dependencies = [ [[package]] name = "swc_core" -version = "0.90.33" +version = "0.92.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b671d6b61601035da37d2734797321644821152f87db4502405eed6574de728b" +checksum = "e317f6f8b15019358d1e48631c0e6d098d9a3d00d666ea99650201661abea855" dependencies = [ "binding_macros", "swc", @@ -8330,9 +7923,9 @@ dependencies = [ [[package]] name = "swc_css_ast" -version = "0.140.22" +version = "0.140.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eeb244560d41d5885c5d86623c0fb25d1e3783edcdf878f2572d1952010955e" +checksum = "be69b267990e9727881125d39b3a2b8204bb2f85b9ece2ad3e212a1fe5c79bea" dependencies = [ "is-macro", "string_enum", @@ -8342,9 +7935,9 @@ dependencies = [ [[package]] name = "swc_css_codegen" -version = "0.151.33" +version = "0.151.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4dc37f8b8ee3cac9b24bb385c63ddd7bda41a641e147fd18e90036604a9acf1" +checksum = "dc65d732bd6fd1757a14dc4636b762d9224fc83f1f978b6a5840b843a3964bde" dependencies = [ "auto_impl", "bitflags 2.5.0", @@ -8359,9 +7952,9 @@ dependencies = [ [[package]] name = "swc_css_codegen_macros" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0db1d634bcd2df2b694e2bf9320b8f808db3451e35d70e36252966b551a11ef4" +checksum = "de2ece8c7dbdde85aa1bcc9764c5f41f7450d8bf1312eac2375b8dc0ecbc13d7" dependencies = [ "proc-macro2", "quote", @@ -8371,9 +7964,9 @@ dependencies = [ [[package]] name = "swc_css_compat" -version = "0.27.34" +version = "0.27.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b65ee8377e112ffe8e1a01147ef5622a51e9c9bf63e85ed21e0a184f91f50f41" +checksum = "c3973cc69eb96e64798f506fe57c5ad1d9a24fd7cf870250144e110d000ce045" dependencies = [ "bitflags 2.5.0", "once_cell", @@ -8388,9 +7981,9 @@ dependencies = [ [[package]] name = "swc_css_minifier" -version = "0.116.33" +version = "0.116.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee993aeb2314bad3b1ac2449f142a230c204443749a96a3c807f34bf8d845ad6" +checksum = "1bee9bb889f46af0e7426ace32cc2150d4e56f1a3376377d9ed51101bea29d35" dependencies = [ "serde", "swc_atoms", @@ -8402,9 +7995,9 @@ dependencies = [ [[package]] name = "swc_css_modules" -version = "0.29.34" +version = "0.29.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "209966e658fb11773a8d14c004554fdc667f6d44128942c47f3d0195cf483613" +checksum = "b20af192df5adddac04293b5072cc00befa2d6818a9fc90ac6f5c2c49e82dd1c" dependencies = [ "rustc-hash", "serde", @@ -8418,9 +8011,9 @@ dependencies = [ [[package]] name = "swc_css_parser" -version = "0.150.32" +version = "0.150.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf0b402ad8f51d62e8af1d22ea093881147dbc6fd46cba2634df66add05945ec" +checksum = "174995d62f066e4a4091c03ce9d35233cf8a2e23d729c2041cd5c2b3e2af2d1e" dependencies = [ "lexical", "serde", @@ -8431,9 +8024,9 @@ dependencies = [ [[package]] name = "swc_css_prefixer" -version = "0.153.36" +version = "0.153.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f202bf9b7eec1e87c74bf4be8677e1086d8bbf9832f57829f5d106c62a6e715" +checksum = "12416e97bced06666368f3cf7801abacb1a8962c9a4b9b2924faa4f45dc512aa" dependencies = [ "once_cell", "preset_env_base", @@ -8448,9 +8041,9 @@ dependencies = [ [[package]] name = "swc_css_utils" -version = "0.137.22" +version = "0.137.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fb7bc3fd90d4e0ad270b255d20e7172f26c26bd91d8b8c709b54690a2f209a3" +checksum = "a890e543134dc78ac46d0ffce3028d37b639f8854f25aaef67178111459ba021" dependencies = [ "once_cell", "serde", @@ -8463,9 +8056,9 @@ dependencies = [ [[package]] name = "swc_css_visit" -version = "0.139.21" +version = "0.139.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2bc4deb5540e3869f74e09997b2dd9e1d7b3f750ba2c910f88041f8027868c5" +checksum = "d5f0f267339cff49928e87b68ba453e85808eb11d660c720b3eb9c1c8510ad7a" dependencies = [ "serde", "swc_atoms", @@ -8476,9 +8069,9 @@ dependencies = [ [[package]] name = "swc_ecma_ast" -version = "0.112.8" +version = "0.113.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1d5c33c22ad50e8e34b3080a6fb133316d2eaa7d00400fc5018151f5ca44c5a" +checksum = "dc1690cc0c9ab60b44ac0225ba1e231ac532f7ba1d754df761c6ee607561afae" dependencies = [ "bitflags 2.5.0", "bytecheck", @@ -8496,9 +8089,9 @@ dependencies = [ [[package]] name = "swc_ecma_codegen" -version = "0.148.16" +version = "0.149.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fb89c03991afedda9dc1ea1bff66dc560a3921a90367927a3831938dc59a0f0" +checksum = "4fef147127a2926ca26171c7afcbf028ff86dc543ced87d316713f25620a15b9" dependencies = [ "memchr", "num-bigint", @@ -8515,9 +8108,9 @@ dependencies = [ [[package]] name = "swc_ecma_codegen_macros" -version = "0.7.5" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17ab87ba81ae05efd394ab4a8cbdba595ac3554a5e393c76699449d47c43582e" +checksum = "090e409af49c8d1a3c13b3aab1ed09dd4eda982207eb3e63c2ad342f072b49c8" dependencies = [ "proc-macro2", "quote", @@ -8527,9 +8120,9 @@ dependencies = [ [[package]] name = "swc_ecma_compat_bugfixes" -version = "0.4.18" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f5396aca4707f5bb34bee83160864209a45b7117ea76932daedcb9109541f40" +checksum = "47dad0d8b1c4ca3264a8c5ac59a10127e4f1c3ec5ed271692c8897228f306d05" dependencies = [ "swc_atoms", "swc_common", @@ -8544,9 +8137,9 @@ dependencies = [ [[package]] name = "swc_ecma_compat_common" -version = "0.4.13" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b06844b66a86b8f3bad66888500fd8fe1e4ac09612c5ae0946ca3f77b81f6b0" +checksum = "d888bcaea9c3b8178ea4abf65adf64457a95a5dd3a3c109a69e02c3c38878e96" dependencies = [ "swc_common", "swc_ecma_ast", @@ -8557,16 +8150,16 @@ dependencies = [ [[package]] name = "swc_ecma_compat_es2015" -version = "0.4.19" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "260948998b33771db552037ea693a7a3e5c853b62431691272185878edab17f7" +checksum = "248532f9ae603be6bf4763f66f74ad0dfd82d6307be876ccf4c5d081826a1161" dependencies = [ "arrayvec 0.7.4", "indexmap 2.2.3", "is-macro", "serde", "serde_derive", - "smallvec 1.13.1", + "smallvec", "swc_atoms", "swc_common", "swc_config", @@ -8583,9 +8176,9 @@ dependencies = [ [[package]] name = "swc_ecma_compat_es2016" -version = "0.4.16" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c75e868ae64fe2625c8aae1f929bae734500ae336d37731f6d4bdf66b8e3b8d3" +checksum = "8d7222c8114ae47fb2e46a65f426b125edab523192e835aecbe3136541f96500" dependencies = [ "swc_atoms", "swc_common", @@ -8600,9 +8193,9 @@ dependencies = [ [[package]] name = "swc_ecma_compat_es2017" -version = "0.4.17" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a4b59b144c818b639e741b0538fb70cd08500e03b3f399e3aef7b774dac1cf1" +checksum = "8ccdc725616ef5a558fb905b991cf328a3a36a4d1b8423173708a02568077a14" dependencies = [ "serde", "swc_atoms", @@ -8618,9 +8211,9 @@ dependencies = [ [[package]] name = "swc_ecma_compat_es2018" -version = "0.4.17" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cced4ec764d3bda35ef5451a260dc747e5ce1f179372aa09ff77bb57c42cfb0c" +checksum = "4a6c329c3980fb20c6c3f7f2afc94975bfe640d53dbb90b74a4707a514f16882" dependencies = [ "serde", "swc_atoms", @@ -8637,9 +8230,9 @@ dependencies = [ [[package]] name = "swc_ecma_compat_es2019" -version = "0.4.16" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a984708b06d662df1c10c2fc06bf98562c6ea3bb93c0e4d5491ee8e61c08e00" +checksum = "f1934f5021e80f6b76e5e0bd06e331d719eb9541c13cb5c128a2b994931952a4" dependencies = [ "swc_atoms", "swc_common", @@ -8653,9 +8246,9 @@ dependencies = [ [[package]] name = "swc_ecma_compat_es2020" -version = "0.4.17" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d4b23ada85bf580f4e1639e54ab237c566a7c319c6e2d1f8010ae5323d0d1ba" +checksum = "0aeddeba198fef2e0ed2bc4a5a0b412a04063f062dc47f93e191b492fc07db4f" dependencies = [ "serde", "swc_atoms", @@ -8671,9 +8264,9 @@ dependencies = [ [[package]] name = "swc_ecma_compat_es2021" -version = "0.4.16" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab566642dff583a16b7b188cf9effc6ae603ea2172769f7a3e7fc1aaf41b67b3" +checksum = "288ad7b2cc410dc4fb08687915c1f588f6a714d737e0a4d4128657124902bcae" dependencies = [ "swc_atoms", "swc_common", @@ -8687,9 +8280,9 @@ dependencies = [ [[package]] name = "swc_ecma_compat_es2022" -version = "0.4.17" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75a3b535284aa37b89b608544508a12ac9770193eec5b2a3c015e94d32f32cfd" +checksum = "8d4a8a9fde6f96316e8b0792a72baa209277e0ce3050b476ee3ab408ec579a2d" dependencies = [ "swc_atoms", "swc_common", @@ -8706,9 +8299,9 @@ dependencies = [ [[package]] name = "swc_ecma_compat_es3" -version = "0.4.16" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3678f2454374d8aefe0997fa32089dd2c3f06d20ecaa0d1fa30c0d3e9871c79b" +checksum = "bc88d41bf1d86c163997a48b10ad47a40d2d0c8b9c6ee03ead151d0022975789" dependencies = [ "swc_common", "swc_ecma_ast", @@ -8721,9 +8314,9 @@ dependencies = [ [[package]] name = "swc_ecma_ext_transforms" -version = "0.113.13" +version = "0.114.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d02e315207f4c6fd0a1a475039b2874392e46a04d1a297c9c66ef0082d9fce" +checksum = "259b7b69630aafde63c6304eeacb93fd54619cbdb199c978549acc76cd512d76" dependencies = [ "phf 0.11.2", "swc_atoms", @@ -8735,13 +8328,13 @@ dependencies = [ [[package]] name = "swc_ecma_lints" -version = "0.92.21" +version = "0.93.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23c5c0dc62f29e6aafa3714b585a67280f2102a6925f1ed280ac1826a352ff26" +checksum = "e66af960e41704f081a2e5dd012c304f9e74bacf8846d70f5c653b32b7f7845a" dependencies = [ "auto_impl", "dashmap", - "parking_lot 0.12.1", + "parking_lot", "rayon", "regex", "serde", @@ -8755,16 +8348,16 @@ dependencies = [ [[package]] name = "swc_ecma_loader" -version = "0.45.26" +version = "0.45.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46ed3847b7c2a70af9a422b24430f7386d70bf3d0408a54991be383f1c3aa954" +checksum = "92c68f934bd2c51f29c4ad0bcae09924e9dc30d7ce0680367d45b42d40338a67" dependencies = [ "anyhow", "dashmap", "lru 0.10.0", "normpath", "once_cell", - "parking_lot 0.12.1", + "parking_lot", "path-clean 0.1.0", "pathdiff", "serde", @@ -8777,16 +8370,16 @@ dependencies = [ [[package]] name = "swc_ecma_minifier" -version = "0.192.23" +version = "0.194.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1feab97d24c9931c5e88dca7730e6a6d4c7689ced9ba05814d9092651b3534db" +checksum = "535bbb8adbdf730302f477948557a26e5cd73854d4543c0630e05132ffa16d8a" dependencies = [ "arrayvec 0.7.4", "indexmap 2.2.3", "num-bigint", "num_cpus", "once_cell", - "parking_lot 0.12.1", + "parking_lot", "radix_fmt", "rayon", "regex", @@ -8811,9 +8404,9 @@ dependencies = [ [[package]] name = "swc_ecma_parser" -version = "0.143.15" +version = "0.144.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6a9fcc676d603f70f32797f20c2909c14117b5d510092e049c71c93595764d4" +checksum = "0499e69683ae5d67a20ff0279b94bc90f29df7922a46331b54d5dd367bf89570" dependencies = [ "either", "new_debug_unreachable", @@ -8821,7 +8414,7 @@ dependencies = [ "num-traits", "phf 0.11.2", "serde", - "smallvec 1.13.1", + "smallvec", "smartstring", "stacker", "swc_atoms", @@ -8833,9 +8426,9 @@ dependencies = [ [[package]] name = "swc_ecma_preset_env" -version = "0.206.17" +version = "0.207.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e30d4cf2d63c2094d22a2778537353ea817f91c42c2e3bafc88cbe064b1f681" +checksum = "b5969314bf66a4cca45b0401689dd0c74e568c69243ce46f2342d59219e1283c" dependencies = [ "anyhow", "dashmap", @@ -8843,7 +8436,7 @@ dependencies = [ "once_cell", "preset_env_base", "rustc-hash", - "semver 1.0.18", + "semver 1.0.23", "serde", "serde_json", "st-map", @@ -8858,9 +8451,9 @@ dependencies = [ [[package]] name = "swc_ecma_quote_macros" -version = "0.54.13" +version = "0.55.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49a0e789f5cced50904847f0fefef0f416156c12f0e0cf8b054f6fba6233023a" +checksum = "cfc3a759d2885a78cd2a6ac1c1865eb6be02cafe35fbb6c5abd3720d0fca559a" dependencies = [ "anyhow", "proc-macro2", @@ -8875,9 +8468,9 @@ dependencies = [ [[package]] name = "swc_ecma_testing" -version = "0.22.22" +version = "0.22.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c5704ef494b1805bc4566ff566b964bc1e9d3fb0f0e046ad6392b09a54de844" +checksum = "dbe778ce5eae6a7e620e1f6b5326e78f00203c4548e0c659fd22da8be0538fd1" dependencies = [ "anyhow", "hex", @@ -8888,9 +8481,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms" -version = "0.229.18" +version = "0.230.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eb90c2d122976f3e32bf41a2bf710f01e51ef34ef50108992b185cc1cc53e28" +checksum = "b37b4301415b83165109b94c99f9ac62b38fd1da625bfc830883d65d29a473f9" dependencies = [ "swc_atoms", "swc_common", @@ -8908,9 +8501,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_base" -version = "0.137.20" +version = "0.138.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b59fad924fb4fbd7a67e3992751a3f8d205f1f548ce73b9e5abdf5bd83af370" +checksum = "eddb95c2bdad1c9c29edf35712e1e0f9b9ddc1cdb5ba2d582fd93468cb075a03" dependencies = [ "better_scoped_tls", "bitflags 2.5.0", @@ -8920,7 +8513,7 @@ dependencies = [ "rayon", "rustc-hash", "serde", - "smallvec 1.13.1", + "smallvec", "swc_atoms", "swc_common", "swc_ecma_ast", @@ -8932,9 +8525,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_classes" -version = "0.126.16" +version = "0.127.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47af84e64f0216f110839f5552a615d07ed74b45757927f29482700966ab4e97" +checksum = "53043d81678f3c693604eeb1d1f0fe6ba10f303104a31b954dbeebed9cadf530" dependencies = [ "swc_atoms", "swc_common", @@ -8946,9 +8539,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_compat" -version = "0.163.19" +version = "0.164.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed183e0eb761a1eddd9ef2232612bcd6790a9fb8b6dd1885b2a9ea0a2f93752c" +checksum = "7d4e2942c5d8b7afdf81b8d1eec2f4a961aa9fc89ab05ebe5cbd0f6066b60afc" dependencies = [ "arrayvec 0.7.4", "indexmap 2.2.3", @@ -8956,7 +8549,7 @@ dependencies = [ "num-bigint", "rayon", "serde", - "smallvec 1.13.1", + "smallvec", "swc_atoms", "swc_common", "swc_config", @@ -8983,9 +8576,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_macros" -version = "0.5.4" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17e309b88f337da54ef7fe4c5b99c2c522927071f797ee6c9fb8b6bf2d100481" +checksum = "500a1dadad1e0e41e417d633b3d6d5de677c9e0d3159b94ba3348436cdb15aab" dependencies = [ "proc-macro2", "quote", @@ -8995,9 +8588,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_module" -version = "0.180.19" +version = "0.181.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "914cbfb4d9e9aa4b0a5a63c01fb4c2edfa8d7486bec0b891a5e15a94615453a2" +checksum = "477b6ac686dc1e4ab1af5cc6e8417facca0d4e71ce27df0e759c94d8c365c8e2" dependencies = [ "Inflector", "anyhow", @@ -9022,9 +8615,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_optimization" -version = "0.198.21" +version = "0.199.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9f79c85fadc9e4d06cafba9b646a559d0c401ca2d2dc0b5ec8600351042c8b7" +checksum = "32ea30b3df748236c619409f222f0ba68ebeebc08dfff109d2195664a15689f9" dependencies = [ "dashmap", "indexmap 2.2.3", @@ -9047,14 +8640,14 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_proposal" -version = "0.171.23" +version = "0.172.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a00e0cc7d9cfb3935354a43455116636b001d34d103304883b90837cd87f048c" +checksum = "7fbc414d6a9c5479cfb4c6e92fcdac504582bd7bc89a0ed7f8808b72dc8bd1f0" dependencies = [ "either", "rustc-hash", "serde", - "smallvec 1.13.1", + "smallvec", "swc_atoms", "swc_common", "swc_ecma_ast", @@ -9067,9 +8660,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_react" -version = "0.183.19" +version = "0.184.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2570aa788b03d38404558d4822c7b88a35a930a47cf2417cc7732a032015e43d" +checksum = "565a76c4ca47ce31d78301c0beab878e4c2cb4f624691254d834ec8c0e236755" dependencies = [ "base64 0.21.4", "dashmap", @@ -9077,7 +8670,7 @@ dependencies = [ "once_cell", "rayon", "serde", - "sha-1 0.10.0", + "sha-1", "string_enum", "swc_atoms", "swc_common", @@ -9092,9 +8685,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_testing" -version = "0.140.18" +version = "0.141.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c0ea6f85b7bf04391a172d7a369e49865effa77ec3a6cd0e969a274cfcb982d" +checksum = "686445efd086ca6dd52874b4d1935663914e2fb76514c0ad7b0105cec7859451" dependencies = [ "ansi_term", "anyhow", @@ -9118,9 +8711,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_typescript" -version = "0.188.19" +version = "0.189.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af4aa805d31f534cf230ea43282c1d58e580da2c470e3a95cb9f06f5039e5377" +checksum = "e209026c1d3c577cafac257d87e7c0d23119282fbdc8ed03d7f56077e95beb90" dependencies = [ "ryu-js", "serde", @@ -9135,9 +8728,9 @@ dependencies = [ [[package]] name = "swc_ecma_usage_analyzer" -version = "0.23.14" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b82af8ae5c6e5c1c1bdef70d5fb3ef16917985031f8688a7342c10a2123cfa6b" +checksum = "2d140be135c1af1726ee02406ad210c6598b3399303974d884b1b681563602c9" dependencies = [ "indexmap 2.2.3", "rustc-hash", @@ -9152,9 +8745,9 @@ dependencies = [ [[package]] name = "swc_ecma_utils" -version = "0.127.19" +version = "0.128.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95eb7d0729c17e7b1bddfc67b26f120efa69ae0c9f39738bb5eb8aa154a31cb9" +checksum = "fe5242670bc74e0a0b64b9d4912b37be36944517ce0881314162aeb4381272c3" dependencies = [ "indexmap 2.2.3", "num_cpus", @@ -9171,9 +8764,9 @@ dependencies = [ [[package]] name = "swc_ecma_visit" -version = "0.98.7" +version = "0.99.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93692bdcdbb63db8f5e10fea5d202b5487cb27eb443aec424f4335c88f9864af" +checksum = "28a6ce28ad8e591f8d627f1f9cb26b25e5d83052a9bc1b674d95fc28040cfa98" dependencies = [ "num-bigint", "serde", @@ -9186,11 +8779,11 @@ dependencies = [ [[package]] name = "swc_emotion" -version = "0.72.8" +version = "0.72.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c43a5946f5e0ea03341b23786e43e3fa07eaa014f03fb39cf584b02c38e9c80c" +checksum = "4b454c1b99da4da9aab3731ab34d7582d2eab96e47670d0c62711053886ef7e2" dependencies = [ - "base64 0.13.1", + "base64 0.22.1", "byteorder", "fxhash", "once_cell", @@ -9221,22 +8814,22 @@ dependencies = [ [[package]] name = "swc_error_reporters" -version = "0.17.19" +version = "0.17.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3329e73f159a3d38d4cd5f606a0918eeff39f5bbdbdafd9b6fecb290d2e9a32d" +checksum = "72100a5f7b0c178adf7bcc5e7c8ad9d4180f499a5f5bae9faf3f417c7cbc4915" dependencies = [ "anyhow", "miette 4.7.1", "once_cell", - "parking_lot 0.12.1", + "parking_lot", "swc_common", ] [[package]] name = "swc_fast_graph" -version = "0.21.21" +version = "0.21.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54db83cdbd924cc8b5082ab54ff2a1b4f53ecde8f53c87b9f9c877c9daef4569" +checksum = "f3fdd64bc3d161d6c1ea9a8ae5779e4ba132afc67e7b8ece5420bfc9c6e1275d" dependencies = [ "indexmap 2.2.3", "petgraph", @@ -9246,9 +8839,9 @@ dependencies = [ [[package]] name = "swc_graph_analyzer" -version = "0.22.22" +version = "0.22.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b66d0e18899b3a69eca103e5b4af2f0c837427aa07a60be1c4ceb4346ea245" +checksum = "c728a8f9b82b7160a1ae246e31232177b371f827eb0d01006c0f120a3494871c" dependencies = [ "auto_impl", "petgraph", @@ -9259,9 +8852,9 @@ dependencies = [ [[package]] name = "swc_macros_common" -version = "0.3.10" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5be7766a95a2840ded618baeaab63809b71230ef19094b34f76c8af4d85aa2" +checksum = "91745f3561057493d2da768437c427c0e979dff7396507ae02f16c981c4a8466" dependencies = [ "proc-macro2", "quote", @@ -9280,9 +8873,9 @@ dependencies = [ [[package]] name = "swc_node_comments" -version = "0.20.19" +version = "0.20.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd75c635e4b54961c1c8dc693bb16eb70497eb8a2564f303089a9a66e81ed7ae" +checksum = "d39218bffecf32538d94a22791a12ff6f65e618edcc632d42e065a4e9c773065" dependencies = [ "dashmap", "swc_atoms", @@ -9316,9 +8909,9 @@ dependencies = [ [[package]] name = "swc_plugin_proxy" -version = "0.41.7" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e09ebf5da9eb13f431ebfb916cd3378a87ffae927ba896261ebc9dc094457ae" +checksum = "98974702046356b67da841a8de561480fd75f963f5d406eee40d690e014e4b55" dependencies = [ "better_scoped_tls", "rkyv", @@ -9330,15 +8923,15 @@ dependencies = [ [[package]] name = "swc_plugin_runner" -version = "0.106.16" +version = "0.107.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41c4b6d5c4ea05c3ddd68702736cf524661cde1200185ee8c27f10c4a5811a3d" +checksum = "73640537e0967a88a537c853de4a41ba6cdf77bfff1999f7c6c449e5bc550eed" dependencies = [ "anyhow", "enumset", - "futures 0.3.30", + "futures", "once_cell", - "parking_lot 0.12.1", + "parking_lot", "serde", "serde_json", "swc_common", @@ -9355,9 +8948,9 @@ dependencies = [ [[package]] name = "swc_relay" -version = "0.44.8" +version = "0.44.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68cd77d63c87626434782b9542e4a1335490200cee86e03e1cb6c61fccc71a30" +checksum = "b36a22861087d88f0ae4d78800b6fd44e2dc5b541f8da53e81388c611bab0ef9" dependencies = [ "once_cell", "regex", @@ -9373,9 +8966,9 @@ dependencies = [ [[package]] name = "swc_timer" -version = "0.21.21" +version = "0.21.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e75ce0373fd1b75a021073d796201d5af15106857fc0a801e31379e9e04891e9" +checksum = "0c05c13aecc7a128f86273004f57b5964a6e8828a90e542f362deaed7985504f" dependencies = [ "tracing", ] @@ -9393,9 +8986,9 @@ dependencies = [ [[package]] name = "swc_visit" -version = "0.5.13" +version = "0.5.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0263be55289abfe9c877ffef83d877b5bdfac036ffe2de793f48f5e47e41dbae" +checksum = "043d11fe683dcb934583ead49405c0896a5af5face522e4682c16971ef7871b9" dependencies = [ "either", "swc_visit_macros", @@ -9403,9 +8996,9 @@ dependencies = [ [[package]] name = "swc_visit_macros" -version = "0.5.11" +version = "0.5.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33fc817055fe127b4285dc85058596768bfde7537ae37da82c67815557f03e33" +checksum = "4ae9ef18ff8daffa999f729db056d2821cd2f790f3a11e46422d19f46bb193e7" dependencies = [ "Inflector", "proc-macro2", @@ -9471,13 +9064,13 @@ version = "0.27.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a902e9050fca0a5d6877550b769abd2bd1ce8c04634b941dbe2809735e1a1e33" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "core-foundation-sys", "libc", "ntapi", "once_cell", "rayon", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -9576,7 +9169,7 @@ version = "3.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "fastrand 2.0.0", "redox_syscall 0.3.5", "rustix 0.38.31", @@ -9590,7 +9183,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e4129646ca0ed8f45d09b929036bafad5377103edd06e50bf574b353d2b08d9" dependencies = [ "libc", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -9609,7 +9202,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df" dependencies = [ "libc", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -9671,7 +9264,7 @@ version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72dc21b5887f4032c4656502d085dc28f2afbb686f25f216472bb0526f4b1b88" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "proc-macro-error", "proc-macro2", "quote", @@ -9693,9 +9286,9 @@ dependencies = [ [[package]] name = "testing" -version = "0.35.23" +version = "0.35.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "689e2661712768726869f62945ccbe5d76ab3a3957b88221275bebe22a0761c8" +checksum = "c71dd5265f4921fe51b386b1496c63ac058589d8cd38de6b61489a98c6019a16" dependencies = [ "ansi_term", "cargo_metadata", @@ -9777,7 +9370,7 @@ version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "once_cell", ] @@ -9801,17 +9394,6 @@ dependencies = [ "tikv-jemalloc-sys", ] -[[package]] -name = "time" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" -dependencies = [ - "libc", - "wasi 0.10.0+wasi-snapshot-preview1", - "winapi 0.3.9", -] - [[package]] name = "time" version = "0.3.30" @@ -9891,11 +9473,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9" dependencies = [ "backtrace", - "bytes 1.5.0", + "bytes", "libc", - "mio 0.8.8", + "mio", "num_cpus", - "parking_lot 0.12.1", + "parking_lot", "pin-project-lite", "signal-hook-registry", "socket2 0.5.4", @@ -9904,38 +9486,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "tokio-codec" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25b2998660ba0e70d18684de5d06b70b70a3a747469af9dea7618cc59e75976b" -dependencies = [ - "bytes 0.4.12", - "futures 0.1.31", - "tokio-io", -] - -[[package]] -name = "tokio-executor" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb2d1b8f4548dbf5e1f7818512e9c406860678f29c300cdf0ebac72d1a3a1671" -dependencies = [ - "crossbeam-utils 0.7.2", - "futures 0.1.31", -] - -[[package]] -name = "tokio-io" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57fc868aae093479e3131e3d165c93b1c7474109d13c90ec0dda2a1bbfff0674" -dependencies = [ - "bytes 0.4.12", - "futures 0.1.31", - "log 0.4.20", -] - [[package]] name = "tokio-io-timeout" version = "1.2.0" @@ -9967,25 +9517,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "tokio-reactor" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09bc590ec4ba8ba87652da2068d150dcada2cfa2e07faae270a5e0409aa51351" -dependencies = [ - "crossbeam-utils 0.7.2", - "futures 0.1.31", - "lazy_static", - "log 0.4.20", - "mio 0.6.23", - "num_cpus", - "parking_lot 0.9.0", - "slab", - "tokio-executor", - "tokio-io", - "tokio-sync", -] - [[package]] name = "tokio-retry" version = "0.3.0" @@ -10029,41 +9560,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "tokio-sync" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edfe50152bc8164fcc456dab7891fa9bf8beaf01c5ee7e1dd43a397c3cf87dee" -dependencies = [ - "fnv", - "futures 0.1.31", -] - -[[package]] -name = "tokio-tcp" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98df18ed66e3b72e742f185882a9e201892407957e45fbff8da17ae7a7c51f72" -dependencies = [ - "bytes 0.4.12", - "futures 0.1.31", - "iovec", - "mio 0.6.23", - "tokio-io", - "tokio-reactor", -] - -[[package]] -name = "tokio-tls" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "354b8cd83825b3c20217a9dc174d6a0c67441a2fae5c41bcb1ea6679f6ae0f7c" -dependencies = [ - "futures 0.1.31", - "native-tls", - "tokio-io", -] - [[package]] name = "tokio-tungstenite" version = "0.18.0" @@ -10071,9 +9567,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "54319c93411147bced34cb5609a80e0a8e44c5999c93903a81cd866630ec0bfd" dependencies = [ "futures-util", - "log 0.4.20", + "log", "tokio", - "tungstenite", + "tungstenite 0.18.0", ] [[package]] @@ -10082,7 +9578,7 @@ version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" dependencies = [ - "bytes 1.5.0", + "bytes", "futures-core", "futures-io", "futures-sink", @@ -10169,15 +9665,15 @@ dependencies = [ "async-trait", "axum", "base64 0.13.1", - "bytes 1.5.0", + "bytes", "futures-core", "futures-util", "h2", - "http", + "http 0.2.11", "http-body", - "hyper 0.14.28", + "hyper", "hyper-timeout", - "percent-encoding 2.3.0", + "percent-encoding", "pin-project", "prost 0.11.8", "prost-derive 0.11.8", @@ -10201,13 +9697,13 @@ dependencies = [ "async-trait", "axum", "base64 0.21.4", - "bytes 1.5.0", + "bytes", "h2", - "http", + "http 0.2.11", "http-body", - "hyper 0.14.28", + "hyper", "hyper-timeout", - "percent-encoding 2.3.0", + "percent-encoding", "pin-project", "prost 0.12.3", "tokio", @@ -10265,9 +9761,9 @@ checksum = "d4ba052b54a6627628d9b3c34c176e7eda8359b7da9acd497b9f20998d118508" dependencies = [ "async-trait", "auto_impl", - "bytes 1.5.0", + "bytes", "dashmap", - "futures 0.3.30", + "futures", "httparse", "lsp-types", "memchr", @@ -10314,7 +9810,7 @@ version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ - "log 0.4.20", + "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -10327,7 +9823,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09d48f71a791638519505cefafe162606f706c25592e4bde4d97600c0195312e" dependencies = [ "crossbeam-channel", - "time 0.3.30", + "time", "tracing-subscriber", ] @@ -10379,7 +9875,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" dependencies = [ - "log 0.4.20", + "log", "once_cell", "tracing-core", ] @@ -10417,7 +9913,7 @@ dependencies = [ "serde", "serde_json", "sharded-slab", - "smallvec 1.13.1", + "smallvec", "thread_local", "tracing", "tracing-core", @@ -10448,12 +9944,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "traitobject" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079" - [[package]] name = "triomphe" version = "0.1.11" @@ -10493,14 +9983,33 @@ checksum = "30ee6ab729cd4cf0fd55218530c4522ed30b7b6081752839b68fcec8d0960788" dependencies = [ "base64 0.13.1", "byteorder", - "bytes 1.5.0", - "http", + "bytes", + "http 0.2.11", "httparse", - "log 0.4.20", + "log", "rand 0.8.5", "sha1", "thiserror", - "url 2.4.1", + "url", + "utf-8", +] + +[[package]] +name = "tungstenite" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ef1a641ea34f399a848dea702823bbecfb4c486f911735368f1f137cb8257e1" +dependencies = [ + "byteorder", + "bytes", + "data-encoding", + "http 1.1.0", + "httparse", + "log", + "rand 0.8.5", + "sha1", + "thiserror", + "url", "utf-8", ] @@ -10516,7 +10025,7 @@ dependencies = [ "miette 5.10.0", "pretty_assertions", "turborepo-lib", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -10530,12 +10039,12 @@ dependencies = [ "dashmap", "erased-serde", "event-listener", - "futures 0.3.30", + "futures", "indexmap 1.9.3", "mopa", "nohash-hasher", "once_cell", - "parking_lot 0.12.1", + "parking_lot", "pin-project-lite", "regex", "serde", @@ -10548,6 +10057,7 @@ dependencies = [ "turbo-tasks-build", "turbo-tasks-hash", "turbo-tasks-macros", + "turbo-tasks-malloc", ] [[package]] @@ -10566,8 +10076,8 @@ name = "turbo-tasks-bytes" version = "0.1.0" dependencies = [ "anyhow", - "bytes 1.5.0", - "futures 0.3.30", + "bytes", + "futures", "serde", "serde_bytes", "serde_test", @@ -10613,20 +10123,20 @@ dependencies = [ "anyhow", "auto-hash-map", "bitflags 1.3.2", - "bytes 1.5.0", + "bytes", "concurrent-queue", "criterion", "dashmap", "dunce", - "futures 0.3.30", + "futures", "futures-retry", "include_dir", "indexmap 1.9.3", "jsonc-parser 0.21.0", - "mime 0.3.17", + "mime", "notify", "notify-debouncer-full", - "parking_lot 0.12.1", + "parking_lot", "rstest", "serde", "serde_json", @@ -10662,6 +10172,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", + "regex", "syn 1.0.109", "turbo-tasks-macros-shared", ] @@ -10706,15 +10217,18 @@ dependencies = [ "dashmap", "indexmap 1.9.3", "lazy_static", + "loom", "nohash-hasher", "num_cpus", "once_cell", - "parking_lot 0.12.1", + "parking_lot", "priority-queue", + "rand 0.8.5", "ref-cast", + "rstest", "rustc-hash", "serde", - "smallvec 1.13.1", + "smallvec", "tokio", "tracing", "turbo-tasks", @@ -10730,7 +10244,7 @@ version = "0.1.0" dependencies = [ "anyhow", "auto-hash-map", - "futures 0.3.30", + "futures", "lazy_static", "tokio", "turbo-tasks", @@ -10743,7 +10257,7 @@ dependencies = [ "atty", "console", "reqwest", - "semver 1.0.18", + "semver 1.0.23", "serde", "thiserror", "update-informer", @@ -10757,7 +10271,7 @@ dependencies = [ "async-recursion", "criterion", "difference", - "futures 0.3.30", + "futures", "indexmap 1.9.3", "lazy_static", "regex", @@ -10792,22 +10306,22 @@ dependencies = [ "anyhow", "chromiumoxide", "criterion", - "futures 0.3.30", + "futures", "nix 0.26.2", "once_cell", "owo-colors", - "parking_lot 0.12.1", + "parking_lot", "portpicker", "rand 0.8.5", "regex", "serde_json", "tempfile", "tokio", - "tungstenite", + "tungstenite 0.18.0", "turbo-tasks", "turbo-tasks-testing", "turbopack-create-test-app", - "url 2.4.1", + "url", ] [[package]] @@ -10859,6 +10373,7 @@ dependencies = [ "turbopack-static", "turbopack-swc-utils", "turbopack-test-utils", + "turbopack-trace-server", "turbopack-trace-utils", ] @@ -10893,8 +10408,8 @@ dependencies = [ "console-subscriber", "criterion", "dunce", - "futures 0.3.30", - "mime 0.3.17", + "futures", + "mime", "owo-colors", "regex", "serde", @@ -10920,6 +10435,7 @@ dependencies = [ "turbopack-node", "turbopack-nodejs", "turbopack-resolve", + "turbopack-trace-server", "turbopack-trace-utils", "webbrowser", ] @@ -10949,7 +10465,7 @@ dependencies = [ "async-trait", "auto-hash-map", "browserslist-rs", - "futures 0.3.30", + "futures", "indexmap 1.9.3", "lazy_static", "once_cell", @@ -10997,7 +10513,7 @@ dependencies = [ "parcel_sourcemap", "regex", "serde", - "smallvec 1.13.1", + "smallvec", "swc_core", "tracing", "turbo-tasks", @@ -11017,13 +10533,13 @@ dependencies = [ "anyhow", "async-compression", "auto-hash-map", - "futures 0.3.30", - "hyper 0.14.28", + "futures", + "hyper", "hyper-tungstenite", "indexmap 1.9.3", - "mime 0.3.17", + "mime", "mime_guess", - "parking_lot 0.12.1", + "parking_lot", "pin-project-lite", "serde", "serde_json", @@ -11059,7 +10575,7 @@ dependencies = [ "num-bigint", "num-traits", "once_cell", - "parking_lot 0.12.1", + "parking_lot", "petgraph", "regex", "rstest", @@ -11079,7 +10595,7 @@ dependencies = [ "turbopack-core", "turbopack-resolve", "turbopack-swc-utils", - "url 2.4.1", + "url", "urlencoding", ] @@ -11153,7 +10669,7 @@ dependencies = [ "anyhow", "base64 0.21.4", "image 0.25.0", - "mime 0.3.17", + "mime", "once_cell", "regex", "serde", @@ -11200,14 +10716,14 @@ dependencies = [ "async-stream", "async-trait", "const_format", - "futures 0.3.30", + "futures", "futures-retry", "indexmap 1.9.3", "indoc", - "mime 0.3.17", + "mime", "once_cell", "owo-colors", - "parking_lot 0.12.1", + "parking_lot", "regex", "serde", "serde_json", @@ -11309,7 +10825,7 @@ version = "0.1.0" dependencies = [ "anyhow", "dunce", - "futures 0.3.30", + "futures", "once_cell", "serde", "serde_json", @@ -11344,11 +10860,12 @@ dependencies = [ "indexmap 1.9.3", "itertools 0.10.5", "postcard", + "rayon", "rustc-demangle", "serde", "serde_json", + "tungstenite 0.21.0", "turbopack-trace-utils", - "websocket", "zstd 0.13.1", ] @@ -11406,8 +10923,7 @@ dependencies = [ name = "turborepo-analytics" version = "0.1.0" dependencies = [ - "async-trait", - "futures 0.3.30", + "futures", "thiserror", "tokio", "tracing", @@ -11421,9 +10937,8 @@ name = "turborepo-api-client" version = "0.1.0" dependencies = [ "anyhow", - "async-trait", "chrono", - "http", + "http 0.2.11", "lazy_static", "port_scanner", "regex", @@ -11439,7 +10954,7 @@ dependencies = [ "turborepo-ci", "turborepo-vercel-api", "turborepo-vercel-api-mock", - "url 2.4.1", + "url", ] [[package]] @@ -11467,7 +10982,7 @@ dependencies = [ "turborepo-ui", "turborepo-vercel-api", "turborepo-vercel-api-mock", - "url 2.4.1", + "url", "webbrowser", ] @@ -11478,7 +10993,7 @@ dependencies = [ "anyhow", "base64 0.21.4", "camino", - "futures 0.3.30", + "futures", "hmac", "libc", "os_str_bytes", @@ -11548,7 +11063,7 @@ version = "0.1.0" dependencies = [ "bitflags 1.3.2", "fsevent-sys", - "futures 0.3.30", + "futures", "git2 0.16.1", "itertools 0.10.5", "libc", @@ -11583,9 +11098,9 @@ dependencies = [ name = "turborepo-graph-utils" version = "0.1.0" dependencies = [ - "futures 0.3.30", + "futures", "itertools 0.10.5", - "log 0.4.20", + "log", "petgraph", "thiserror", "tokio", @@ -11623,7 +11138,7 @@ dependencies = [ "dirs-next", "dunce", "either", - "futures 0.3.30", + "futures", "futures-core", "globwalk", "globwatch", @@ -11648,11 +11163,12 @@ dependencies = [ "pprof", "pretty_assertions", "prost 0.12.3", + "radix_trie", "rand 0.8.5", "rayon", "regex", "reqwest", - "semver 1.0.18", + "semver 1.0.23", "serde", "serde_json", "serde_yaml 0.9.27", @@ -11666,7 +11182,7 @@ dependencies = [ "tempfile", "test-case", "thiserror", - "time 0.3.30", + "time", "tiny-gradient", "tokio", "tokio-stream", @@ -11704,7 +11220,7 @@ dependencies = [ "wax", "webbrowser", "which", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -11718,7 +11234,7 @@ dependencies = [ "pretty_assertions", "rayon", "regex", - "semver 1.0.18", + "semver 1.0.23", "serde", "serde_json", "serde_yaml 0.9.27", @@ -11814,10 +11330,9 @@ dependencies = [ name = "turborepo-telemetry" version = "0.1.0" dependencies = [ - "async-trait", "chrono", "config", - "futures 0.3.30", + "futures", "hex", "once_cell", "reqwest", @@ -11835,7 +11350,7 @@ dependencies = [ "turborepo-ui", "turborepo-vercel-api", "turborepo-vercel-api-mock", - "url 2.4.1", + "url", "uuid", ] @@ -11860,7 +11375,7 @@ dependencies = [ "tui-term", "turbopath", "turborepo-vt100", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -11872,7 +11387,7 @@ dependencies = [ "serde", "serde_json", "test-case", - "url 2.4.1", + "url", ] [[package]] @@ -11894,7 +11409,7 @@ name = "turborepo-vt100" version = "0.15.2" dependencies = [ "itoa", - "log 0.4.20", + "log", "quickcheck", "rand 0.8.5", "ratatui", @@ -11912,17 +11427,11 @@ version = "1.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" dependencies = [ - "cfg-if 1.0.0", - "rand 0.8.5", + "cfg-if", + "rand 0.4.6", "static_assertions", ] -[[package]] -name = "typeable" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887" - [[package]] name = "typed-arena" version = "2.0.2" @@ -11948,7 +11457,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce65604324d3cce9b966701489fbd0cf318cb1f7bd9dd07ac9a4ee6fb791930d" dependencies = [ "tempfile", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -12001,22 +11510,13 @@ dependencies = [ "unic-common", ] -[[package]] -name = "unicase" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33" -dependencies = [ - "version_check 0.1.5", -] - [[package]] name = "unicase" version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" dependencies = [ - "version_check 0.9.4", + "version_check", ] [[package]] @@ -12039,9 +11539,9 @@ checksum = "d70b6494226b36008c8366c288d77190b3fad2eb4c10533139c1c1f461127f1a" [[package]] name = "unicode-id-start" -version = "1.1.2" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8f73150333cb58412db36f2aca8f2875b013049705cc77b94ded70a1ab1f5da" +checksum = "02aebfa694eccbbbffdd92922c7de136b9fe764396d2f10e21bce1681477cfc1" [[package]] name = "unicode-ident" @@ -12108,7 +11608,7 @@ checksum = "2f8811797a24ff123db3c6e1087aa42551d03d772b3724be421ad063da1f5f3f" dependencies = [ "directories", "reqwest", - "semver 1.0.18", + "semver 1.0.23", "serde", "serde_json", "ureq", @@ -12122,28 +11622,17 @@ checksum = "f8cdd25c339e200129fe4de81451814e5228c9b771d57378817d6117cc2b3f97" dependencies = [ "base64 0.21.4", "flate2", - "log 0.4.20", + "log", "native-tls", "once_cell", "rustls 0.21.10", "rustls-webpki", "serde", "serde_json", - "url 2.4.1", + "url", "webpki-roots 0.25.3", ] -[[package]] -name = "url" -version = "1.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" -dependencies = [ - "idna 0.1.5", - "matches", - "percent-encoding 1.0.1", -] - [[package]] name = "url" version = "2.4.1" @@ -12151,8 +11640,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" dependencies = [ "form_urlencoded", - "idna 0.4.0", - "percent-encoding 2.3.0", + "idna", + "percent-encoding", "serde", ] @@ -12189,7 +11678,7 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85db69f33d00031c1b07f7292e56317d5aa9475bdbd3d27ef18f3633438a697e" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "noop_proc_macro", "num-derive 0.4.0", "num-traits", @@ -12236,12 +11725,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "579a42fc0b8e0c63b76519a339be31bed574929511fa53c1a3acae26eb258f29" -[[package]] -name = "version_check" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" - [[package]] name = "version_check" version = "0.9.4" @@ -12256,11 +11739,11 @@ checksum = "6ce7b7674a3d0ddb5915b8f4feccdd6e8680c5980c296688e0f0e7378b8c69e1" dependencies = [ "anyhow", "async-trait", - "bytes 1.5.0", + "bytes", "derivative", "filetime", "fs_extra", - "futures 0.3.30", + "futures", "getrandom", "indexmap 1.9.3", "lazy_static", @@ -12282,10 +11765,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9f38a379f14296f9fb93eda42ece4d57b568af417569102c3dcfeb88ab4800f" dependencies = [ "async-trait", - "bytes 1.5.0", + "bytes", "derivative", - "futures 0.3.30", - "mio 0.8.8", + "futures", + "mio", "serde", "socket2 0.4.9", "thiserror", @@ -12302,7 +11785,7 @@ dependencies = [ "async-trait", "base64 0.21.4", "bincode", - "bytes 1.5.0", + "bytes", "derivative", "futures-util", "pin-project-lite", @@ -12485,16 +11968,10 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" dependencies = [ - "log 0.4.20", + "log", "try-lock", ] -[[package]] -name = "wasi" -version = "0.10.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -12507,7 +11984,7 @@ version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1e124130aee3fb58c5bdd6b639a0509486b0338acaaae0c84a5124b0f588b7f" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "wasm-bindgen-macro", ] @@ -12518,7 +11995,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c9e7e1900c352b609c8488ad12639a311045f40a35491fb69ba8c12f758af70b" dependencies = [ "bumpalo", - "log 0.4.20", + "log", "once_cell", "proc-macro2", "quote", @@ -12532,7 +12009,7 @@ version = "0.4.41" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "877b9c3f61ceea0e56331985743b13f3d25c406a7098d45180fb5f09bc19ed97" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "js-sys", "wasm-bindgen", "web-sys", @@ -12582,8 +12059,8 @@ version = "4.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5467c7a23f9be04d5691590bea509dbea27e5ba5810d0020bef908456a495f33" dependencies = [ - "bytes 1.5.0", - "cfg-if 1.0.0", + "bytes", + "cfg-if", "derivative", "indexmap 1.9.3", "js-sys", @@ -12603,7 +12080,7 @@ dependencies = [ "wasmparser 0.83.0", "wasmparser 0.95.0", "wat", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -12625,8 +12102,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "510ad01a668d774f3a103a7c219bbc0970be93e8f1b27e2fdb48d1f4ccd1deff" dependencies = [ "backtrace", - "bytes 1.5.0", - "cfg-if 1.0.0", + "bytes", + "cfg-if", "enum-iterator", "enumset", "lazy_static", @@ -12637,12 +12114,12 @@ dependencies = [ "rkyv", "self_cell", "shared-buffer", - "smallvec 1.13.1", + "smallvec", "thiserror", "wasmer-types", "wasmer-vm", "wasmparser 0.95.0", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -12657,7 +12134,7 @@ dependencies = [ "gimli 0.26.2", "more-asserts", "rayon", - "smallvec 1.13.1", + "smallvec", "target-lexicon", "tracing", "wasmer-compiler", @@ -12685,7 +12162,7 @@ dependencies = [ "anyhow", "derive_builder", "indexmap 2.2.3", - "semver 1.0.18", + "semver 1.0.23", "serde", "serde_cbor", "serde_json", @@ -12719,7 +12196,7 @@ checksum = "58315c25492bc72a33f47a7d7fb0869a0106fc0164ec051e349a9e1eddba9a01" dependencies = [ "backtrace", "cc", - "cfg-if 1.0.0", + "cfg-if", "corosensei", "crossbeam-queue", "dashmap", @@ -12736,7 +12213,7 @@ dependencies = [ "scopeguard", "thiserror", "wasmer-types", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -12748,17 +12225,17 @@ dependencies = [ "anyhow", "async-trait", "bincode", - "bytes 1.5.0", - "cfg-if 1.0.0", + "bytes", + "cfg-if", "chrono", "cooked-waker", "dashmap", "derivative", - "futures 0.3.30", + "futures", "getrandom", "heapless", "hex", - "http", + "http 0.2.11", "js-sys", "lazy_static", "libc", @@ -12768,7 +12245,7 @@ dependencies = [ "pin-project", "rand 0.8.5", "rusty_pool", - "semver 1.0.18", + "semver 1.0.23", "serde", "serde_cbor", "serde_derive", @@ -12781,7 +12258,7 @@ dependencies = [ "thiserror", "tokio", "tracing", - "url 2.4.1", + "url", "urlencoding", "virtual-fs", "virtual-mio", @@ -12796,7 +12273,7 @@ dependencies = [ "web-sys", "webc", "weezl", - "winapi 0.3.9", + "winapi", "xxhash-rust", ] @@ -12809,10 +12286,10 @@ dependencies = [ "anyhow", "bitflags 1.3.2", "byteorder", - "cfg-if 1.0.0", + "cfg-if", "num_enum", "serde", - "time 0.3.30", + "time", "tracing", "wai-bindgen-gen-core", "wai-bindgen-gen-rust", @@ -12837,7 +12314,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2ea896273ea99b15132414be1da01ab0d8836415083298ecaffbe308eaac87a" dependencies = [ "indexmap 1.9.3", - "url 2.4.1", + "url", ] [[package]] @@ -12847,7 +12324,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1dfcdb72d96f01e6c85b6bf20102e7423bdbaad5c337301bab2bbf253d26413c" dependencies = [ "indexmap 2.2.3", - "semver 1.0.18", + "semver 1.0.23", ] [[package]] @@ -12909,11 +12386,11 @@ dependencies = [ "core-foundation", "dirs", "jni", - "log 0.4.20", + "log", "ndk-context", "objc", "raw-window-handle", - "url 2.4.1", + "url", "web-sys", ] @@ -12926,7 +12403,7 @@ dependencies = [ "anyhow", "base64 0.21.4", "byteorder", - "bytes 1.5.0", + "bytes", "flate2", "indexmap 1.9.3", "leb128", @@ -12934,7 +12411,7 @@ dependencies = [ "once_cell", "path-clean 1.0.1", "rand 0.8.5", - "semver 1.0.18", + "semver 1.0.23", "serde", "serde_cbor", "serde_json", @@ -12944,7 +12421,7 @@ dependencies = [ "tempfile", "thiserror", "toml 0.7.8", - "url 2.4.1", + "url", "walkdir", "wasmer-toml", ] @@ -12974,47 +12451,6 @@ version = "0.25.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1778a42e8b3b90bff8d0f5032bf22250792889a5cdc752aa0020c84abe3aaf10" -[[package]] -name = "websocket" -version = "0.27.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a1aba896516545a4cea196a12c04074854ab85d53bbaf22f9b79eddadde75a2" -dependencies = [ - "bytes 0.4.12", - "futures 0.1.31", - "hyper 0.10.16", - "native-tls", - "rand 0.6.5", - "tokio-codec", - "tokio-io", - "tokio-reactor", - "tokio-tcp", - "tokio-tls", - "unicase 1.4.2", - "url 1.7.2", - "websocket-base", -] - -[[package]] -name = "websocket-base" -version = "0.26.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49aec794b07318993d1db16156d5a9c750120597a5ee40c6b928d416186cb138" -dependencies = [ - "base64 0.10.1", - "bitflags 1.3.2", - "byteorder", - "bytes 0.4.12", - "futures 0.1.31", - "native-tls", - "rand 0.6.5", - "sha-1 0.8.2", - "tokio-codec", - "tokio-io", - "tokio-tcp", - "tokio-tls", -] - [[package]] name = "weezl" version = "0.1.8" @@ -13032,12 +12468,6 @@ dependencies = [ "once_cell", ] -[[package]] -name = "winapi" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" - [[package]] name = "winapi" version = "0.3.9" @@ -13048,12 +12478,6 @@ dependencies = [ "winapi-x86_64-pc-windows-gnu", ] -[[package]] -name = "winapi-build" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" - [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" @@ -13066,7 +12490,7 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" dependencies = [ - "winapi 0.3.9", + "winapi", ] [[package]] @@ -13084,6 +12508,35 @@ dependencies = [ "windows-targets 0.48.1", ] +[[package]] +name = "windows" +version = "0.54.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9252e5725dbed82865af151df558e754e4a3c2c30818359eb17465f1346a1b49" +dependencies = [ + "windows-core", + "windows-targets 0.52.5", +] + +[[package]] +name = "windows-core" +version = "0.54.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12661b9c89351d684a50a8a643ce5f608e20243b9fb84687800163429f161d65" +dependencies = [ + "windows-result", + "windows-targets 0.52.5", +] + +[[package]] +name = "windows-result" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "749f0da9cc72d82e600d8d2e44cadd0b9eedb9038f71a1c58556ac1c5791813b" +dependencies = [ + "windows-targets 0.52.5", +] + [[package]] name = "windows-sys" version = "0.33.0" @@ -13136,7 +12589,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.0", + "windows-targets 0.52.5", ] [[package]] @@ -13171,17 +12624,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" dependencies = [ - "windows_aarch64_gnullvm 0.52.0", - "windows_aarch64_msvc 0.52.0", - "windows_i686_gnu 0.52.0", - "windows_i686_msvc 0.52.0", - "windows_x86_64_gnu 0.52.0", - "windows_x86_64_gnullvm 0.52.0", - "windows_x86_64_msvc 0.52.0", + "windows_aarch64_gnullvm 0.52.5", + "windows_aarch64_msvc 0.52.5", + "windows_i686_gnu 0.52.5", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.5", + "windows_x86_64_gnu 0.52.5", + "windows_x86_64_gnullvm 0.52.5", + "windows_x86_64_msvc 0.52.5", ] [[package]] @@ -13198,9 +12652,9 @@ checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" [[package]] name = "windows_aarch64_msvc" @@ -13222,9 +12676,9 @@ checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" [[package]] name = "windows_aarch64_msvc" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" [[package]] name = "windows_i686_gnu" @@ -13246,9 +12700,15 @@ checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" [[package]] name = "windows_i686_gnu" -version = "0.52.0" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" [[package]] name = "windows_i686_msvc" @@ -13270,9 +12730,9 @@ checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" [[package]] name = "windows_i686_msvc" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" [[package]] name = "windows_x86_64_gnu" @@ -13294,9 +12754,9 @@ checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" [[package]] name = "windows_x86_64_gnu" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" [[package]] name = "windows_x86_64_gnullvm" @@ -13312,9 +12772,9 @@ checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" [[package]] name = "windows_x86_64_msvc" @@ -13336,9 +12796,9 @@ checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" [[package]] name = "windows_x86_64_msvc" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" [[package]] name = "winnow" @@ -13355,7 +12815,7 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" dependencies = [ - "winapi 0.3.9", + "winapi", ] [[package]] @@ -13364,17 +12824,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d129932f4644ac2396cb456385cbf9e63b5b30c6e8dc4820bdca4eb082037a5" dependencies = [ - "winapi 0.3.9", -] - -[[package]] -name = "ws2_32-sys" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" -dependencies = [ - "winapi 0.2.8", - "winapi-build", + "winapi", ] [[package]] @@ -13410,7 +12860,7 @@ dependencies = [ "num-format", "owo-colors", "plotters", - "semver 1.0.18", + "semver 1.0.23", "serde", "serde_json", "tabled", diff --git a/Cargo.toml b/Cargo.toml index 1d5e62f472e00..34a37641d5f54 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -77,8 +77,13 @@ turbopack-wasi = [ [workspace.lints.clippy] too_many_arguments = "allow" -[profile.dev.package.turbo-tasks-macros] -opt-level = 3 +# This crate is particularly sensitive to compiler optimizations +[profile.dev.package.turbo-tasks-memory] +opt-level = 1 + +# Set the options for dependencies (not crates in the workspace), this mostly impacts cold builds +[profile.dev.package."*"] +opt-level = 1 # Set the settings for build scripts and proc-macros. [profile.dev.build-override] @@ -103,17 +108,17 @@ async-recursion = "1.0.2" # Keep consistent with preset_env_base through swc_core browserslist-rs = { version = "0.15.0" } miette = { version = "5.10.0", features = ["fancy"] } -mdxjs = "0.1.23" -modularize_imports = { version = "0.68.9" } -styled_components = { version = "0.96.8" } -styled_jsx = { version = "0.73.13" } -swc_core = { version = "0.90.33", features = [ +mdxjs = "0.2.2" +modularize_imports = { version = "0.68.14" } +styled_components = { version = "0.96.15" } +styled_jsx = { version = "0.73.20" } +swc_core = { version = "0.92.5", features = [ "ecma_loader_lru", "ecma_loader_parking_lot", ] } -swc_emotion = { version = "0.72.8" } -swc_relay = { version = "0.44.8" } -testing = { version = "0.35.23" } +swc_emotion = { version = "0.72.13" } +swc_relay = { version = "0.44.13" } +testing = { version = "0.35.24" } # Temporary: Reference the latest git minor version of pathfinder_simd until it's published. pathfinder_simd = "0.5.3" @@ -161,6 +166,7 @@ turbopack-static = { path = "crates/turbopack-static" } turbopack-swc-utils = { path = "crates/turbopack-swc-utils" } turbopack-test-utils = { path = "crates/turbopack-test-utils" } turbopack-tests = { path = "crates/turbopack-tests" } +turbopack-trace-server = { path = "crates/turbopack-trace-server" } turbopack-trace-utils = { path = "crates/turbopack-trace-utils" } turbopack-wasm = { path = "crates/turbopack-wasm" } turbopath = { path = "crates/turborepo-paths" } @@ -259,6 +265,7 @@ pretty_assertions = "1.3.0" proc-macro2 = "1.0.79" qstring = "0.7.2" quote = "1.0.23" +radix_trie = "0.2.1" rand = "0.8.5" ratatui = "0.26.1" regex = "1.7.0" diff --git a/cli/turbo.json b/cli/turbo.json index 6ddf409e6cc8c..7cf7189beb640 100644 --- a/cli/turbo.json +++ b/cli/turbo.json @@ -2,15 +2,9 @@ "$schema": "../docs/public/schema.json", "extends": ["//"], "pipeline": { - "build": { + // A task that is used for detecting if any turborepo Rust sources change + "rust-src": { "env": ["RUNNER_OS"], - "outputs": [ - "../target/debug/turbo", - "../target/debug/turbo.exe", - "../target/release/turbo", - "../target/release/turbo.exe" - ], - "inputs": [ "../version.txt", "../crates/turborepo*/**/*.rs", // Rust crates @@ -19,6 +13,15 @@ "../Cargo.lock", "!../crates/**/target" ] + }, + "build": { + "outputs": [ + "../target/debug/turbo", + "../target/debug/turbo.exe", + "../target/release/turbo", + "../target/release/turbo.exe" + ], + "dependsOn": ["rust-src"] } } } diff --git a/crates/node-file-trace/src/lib.rs b/crates/node-file-trace/src/lib.rs index e34f5e2535df8..34e21c08c5702 100644 --- a/crates/node-file-trace/src/lib.rs +++ b/crates/node-file-trace/src/lib.rs @@ -6,7 +6,6 @@ mod nft_json; use std::{ collections::{BTreeSet, HashMap}, env::current_dir, - fs, future::Future, path::{Path, PathBuf}, pin::Pin, @@ -24,15 +23,12 @@ use serde::Serialize; use tokio::sync::mpsc::channel; use turbo_tasks::{ backend::Backend, util::FormatDuration, TaskId, TransientInstance, TransientValue, TurboTasks, - TurboTasksBackendApi, UpdateInfo, Value, Vc, + UpdateInfo, Value, Vc, }; use turbo_tasks_fs::{ glob::Glob, DirectoryEntry, DiskFileSystem, FileSystem, FileSystemPath, ReadGlobResult, }; -use turbo_tasks_memory::{ - stats::{ReferenceType, Stats}, - viz, MemoryBackend, -}; +use turbo_tasks_memory::MemoryBackend; use turbopack::{ emit_asset, emit_with_completion, module_options::ModuleOptionsContext, rebase::RebasedAsset, ModuleAssetContext, @@ -101,10 +97,6 @@ pub struct CommonArgs { #[cfg_attr(feature = "node-api", serde(default))] cache: CacheArgs, - #[cfg_attr(feature = "cli", clap(short, long))] - #[cfg_attr(feature = "node-api", serde(default))] - visualize_graph: bool, - #[cfg_attr(feature = "cli", clap(short, long))] #[cfg_attr(feature = "node-api", serde(default))] watch: bool, @@ -325,7 +317,6 @@ pub async fn start( ) -> Result> { register(); let &CommonArgs { - visualize_graph, memory_limit, #[cfg(feature = "persistent_cache")] cache: CacheArgs { @@ -390,22 +381,7 @@ pub async fn start( TurboTasks::new(MemoryBackend::new(memory_limit.unwrap_or(usize::MAX))) }) }, - |tt, root_task, _| async move { - if visualize_graph { - let mut stats = Stats::new(); - let b = tt.backend(); - b.with_all_cached_tasks(|task| { - stats.add_id(b, task); - }); - stats.add_id(b, root_task); - // stats.merge_resolve(); - let tree = stats.treeify(ReferenceType::Child); - let graph = - viz::graph::visualize_stats_tree(tree, ReferenceType::Child, tt.stats_type()); - fs::write("graph.html", viz::graph::wrap_html(&graph)).unwrap(); - println!("graph.html written"); - } - }, + |_, _, _| async move {}, module_options, resolve_options, ) diff --git a/crates/turbo-tasks-hash/src/xxh3_hash64.rs b/crates/turbo-tasks-hash/src/xxh3_hash64.rs index 0f1b620619cbc..e5dec287e4b30 100644 --- a/crates/turbo-tasks-hash/src/xxh3_hash64.rs +++ b/crates/turbo-tasks-hash/src/xxh3_hash64.rs @@ -20,13 +20,13 @@ impl Xxh3Hash64Hasher { Self(xxh3::Hash64::with_seed(0)) } - /// Uses the DeterministicHash trait to to hash the input in a + /// Uses the DeterministicHash trait to hash the input in a /// cross-platform way. pub fn write_value(&mut self, input: T) { input.deterministic_hash(self); } - /// Uses the DeterministicHash trait to to hash the input in a + /// Uses the DeterministicHash trait to hash the input in a /// cross-platform way. pub fn write_ref(&mut self, input: &T) { input.deterministic_hash(self); diff --git a/crates/turbo-tasks-macros/Cargo.toml b/crates/turbo-tasks-macros/Cargo.toml index 984ad25fbe8d3..9d6509310a716 100644 --- a/crates/turbo-tasks-macros/Cargo.toml +++ b/crates/turbo-tasks-macros/Cargo.toml @@ -17,5 +17,6 @@ anyhow = { workspace = true } proc-macro-error = "1.0.4" proc-macro2 = { workspace = true } quote = { workspace = true } +regex = { workspace = true } syn = { workspace = true, features = ["full", "extra-traits", "visit-mut"] } turbo-tasks-macros-shared = { workspace = true } diff --git a/crates/turbo-tasks-macros/src/func.rs b/crates/turbo-tasks-macros/src/func.rs index 6afda74a7bad8..a02eb175ae06b 100644 --- a/crates/turbo-tasks-macros/src/func.rs +++ b/crates/turbo-tasks-macros/src/func.rs @@ -1,7 +1,11 @@ use proc_macro2::Ident; use syn::{ - parse_quote, punctuated::Punctuated, spanned::Spanned, Block, Expr, ExprPath, FnArg, Pat, - PatIdent, PatType, Path, Receiver, ReturnType, Signature, Token, Type, + parse_quote, + punctuated::{Pair, Punctuated}, + spanned::Spanned, + AngleBracketedGenericArguments, Block, Expr, ExprPath, FnArg, GenericArgument, Pat, PatIdent, + PatType, Path, PathArguments, PathSegment, Receiver, ReturnType, Signature, Token, Type, + TypeGroup, TypePath, TypeTuple, }; #[derive(Debug)] @@ -257,10 +261,11 @@ impl TurboFn { .collect(); let ident = &self.ident; - let output = &self.output; + let orig_output = &self.output; + let new_output = expand_vc_return_type(orig_output); parse_quote! { - fn #ident(#exposed_inputs) -> <#output as turbo_tasks::task::TaskOutput>::Return + fn #ident(#exposed_inputs) -> #new_output } } @@ -327,6 +332,100 @@ fn return_type_to_type(return_type: &ReturnType) -> Type { } } +fn expand_vc_return_type(orig_output: &Type) -> Type { + // HACK: Approximate the expansion that we'd otherwise get from + // `::Return`, so that the return type shown in the rustdocs + // is as simple as possible. Break out as soon as we see something we don't + // recognize. + let mut new_output = orig_output.clone(); + let mut found_vc = false; + loop { + new_output = match new_output { + Type::Group(TypeGroup { elem, .. }) => *elem, + Type::Tuple(TypeTuple { elems, .. }) if elems.is_empty() => { + Type::Path(parse_quote!(::turbo_tasks::Vc<()>)) + } + Type::Path(TypePath { + qself: None, + path: + Path { + leading_colon, + ref segments, + }, + }) => { + let mut pairs = segments.pairs(); + let mut cur_pair = pairs.next(); + + enum PathPrefix { + Anyhow, + TurboTasks, + } + + // try to strip a `turbo_tasks::` or `anyhow::` prefix + let prefix = if let Some(first) = cur_pair.as_ref().map(|p| p.value()) { + if first.arguments.is_none() { + if first.ident == "turbo_tasks" { + Some(PathPrefix::TurboTasks) + } else if first.ident == "anyhow" { + Some(PathPrefix::Anyhow) + } else { + None + } + } else { + None + } + } else { + None + }; + + if prefix.is_some() { + cur_pair = pairs.next(); // strip the matched prefix + } else if leading_colon.is_some() { + break; // something like `::Vc` isn't valid + } + + // Look for a `Vc<...>` or `Result<...>` generic + let Some(Pair::End(PathSegment { + ident, + arguments: + PathArguments::AngleBracketed(AngleBracketedGenericArguments { args, .. }), + })) = cur_pair + else { + break; + }; + if ident == "Vc" { + found_vc = true; + break; // Vc is the bottom-most level + } + if ident == "Result" && args.len() == 1 { + let GenericArgument::Type(ty) = + args.first().expect("Result<...> type has an argument") + else { + break; + }; + ty.clone() + } else { + break; // we only support expanding Result<...> + } + } + _ => break, + } + } + + if !found_vc { + orig_output + .span() + .unwrap() + .error( + "Expected return type to be `turbo_tasks::Vc` or `anyhow::Result>`. \ + Unable to process type.", + ) + .emit(); + } + + new_output +} + /// The context in which the function is being defined. #[derive(Debug, Clone, Eq, PartialEq)] pub enum DefinitionContext { diff --git a/crates/turbo-tasks-macros/src/value_macro.rs b/crates/turbo-tasks-macros/src/value_macro.rs index f7d57a7696f79..c4393b2e73cde 100644 --- a/crates/turbo-tasks-macros/src/value_macro.rs +++ b/crates/turbo-tasks-macros/src/value_macro.rs @@ -1,9 +1,12 @@ +use std::sync::OnceLock; + use proc_macro::TokenStream; use proc_macro2::Ident; -use quote::quote; +use quote::{quote, ToTokens}; +use regex::Regex; use syn::{ parse::{Parse, ParseStream}, - parse_macro_input, + parse_macro_input, parse_quote, punctuated::Punctuated, spanned::Spanned, Error, Fields, FieldsUnnamed, Generics, Item, ItemEnum, ItemStruct, Lit, LitStr, Meta, @@ -189,7 +192,7 @@ impl Parse for ValueArguments { } pub fn value(args: TokenStream, input: TokenStream) -> TokenStream { - let item = parse_macro_input!(input as Item); + let mut item = parse_macro_input!(input as Item); let ValueArguments { serialization_mode, into_mode, @@ -198,6 +201,58 @@ pub fn value(args: TokenStream, input: TokenStream) -> TokenStream { transparent, } = parse_macro_input!(args as ValueArguments); + let mut inner_type = None; + if transparent { + if let Item::Struct(ItemStruct { + attrs, + fields: Fields::Unnamed(FieldsUnnamed { unnamed, .. }), + .. + }) = &mut item + { + if unnamed.len() == 1 { + let field = unnamed.iter().next().unwrap(); + inner_type = Some(field.ty.clone()); + + // generate a type string to add to the docs + let inner_type_string = inner_type.to_token_stream().to_string(); + + // HACK: proc_macro2 inserts whitespace between every token. It's ugly, so + // remove it, assuming these whitespace aren't syntatically important. Using + // prettyplease (or similar) would be more correct, but slower and add another + // dependency. + static WHITESPACE_RE: OnceLock = OnceLock::new(); + // Remove whitespace, as long as there is a non-word character (e.g. `>` or `,`) + // on either side. Try not to remove whitespace between `dyn Trait`. + let whitespace_re = WHITESPACE_RE.get_or_init(|| { + Regex::new(r"\b \B|\B \b|\B \B").expect("WHITESPACE_RE is valid") + }); + let inner_type_string = whitespace_re.replace_all(&inner_type_string, ""); + + // Add a couple blank lines in case there's already a doc comment we're + // effectively appending to. If there's not, rustdoc will strip + // the leading whitespace. + let doc_str = format!( + "\n\nThis is a [transparent value type][::turbo_tasks::value#transparent] \ + wrapping [`{}`].", + inner_type_string, + ); + + attrs.push(parse_quote! { + #[doc = #doc_str] + }); + } + } + if inner_type.is_none() { + item.span() + .unwrap() + .error( + "#[turbo_tasks::value(transparent)] is only valid with single-item unit \ + structs", + ) + .emit(); + } + } + let ident = match &item { Item::Enum(ItemEnum { ident, .. }) => ident, Item::Struct(ItemStruct { ident, .. }) => ident, @@ -211,20 +266,6 @@ pub fn value(args: TokenStream, input: TokenStream) -> TokenStream { } }; - let mut inner_type = None; - if transparent { - if let Item::Struct(ItemStruct { - fields: Fields::Unnamed(FieldsUnnamed { unnamed, .. }), - .. - }) = &item - { - if unnamed.len() == 1 { - let field = unnamed.iter().next().unwrap(); - inner_type = Some(&field.ty); - } - } - } - let cell_mode = match cell_mode { CellMode::New => quote! { turbo_tasks::VcCellNewMode<#ident> @@ -234,7 +275,7 @@ pub fn value(args: TokenStream, input: TokenStream) -> TokenStream { }, }; - let (cell_prefix, cell_access_content, read) = if let Some(inner_type) = inner_type { + let (cell_prefix, cell_access_content, read) = if let Some(inner_type) = &inner_type { ( quote! { pub }, quote! { diff --git a/crates/turbo-tasks-malloc/src/counter.rs b/crates/turbo-tasks-malloc/src/counter.rs index 74199f2c77527..e0765f51101d1 100644 --- a/crates/turbo-tasks-malloc/src/counter.rs +++ b/crates/turbo-tasks-malloc/src/counter.rs @@ -4,6 +4,8 @@ use std::{ sync::atomic::{AtomicUsize, Ordering}, }; +use crate::AllocationCounters; + static ALLOCATED: AtomicUsize = AtomicUsize::new(0); const KB: usize = 1024; /// When global counter is updates we will keep a thread-local buffer of this @@ -13,23 +15,6 @@ const TARGET_BUFFER: usize = 100 * KB; /// global counter. const MAX_BUFFER: usize = 200 * KB; -#[derive(Default)] -pub struct AllocationInfo { - pub allocations: usize, - pub deallocations: usize, - pub allocation_count: usize, - pub deallocation_count: usize, -} - -impl AllocationInfo { - pub fn is_empty(&self) -> bool { - self.allocations == 0 - && self.deallocations == 0 - && self.allocation_count == 0 - && self.deallocation_count == 0 - } -} - #[derive(Default)] struct ThreadLocalCounter { /// Thread-local buffer of allocated bytes that have been added to the @@ -37,13 +22,13 @@ struct ThreadLocalCounter { /// means the global counter is always equal or greater than the real /// value. buffer: usize, - allocation_info: AllocationInfo, + allocation_counters: AllocationCounters, } impl ThreadLocalCounter { fn add(&mut self, size: usize) { - self.allocation_info.allocations += size; - self.allocation_info.allocation_count += 1; + self.allocation_counters.allocations += size; + self.allocation_counters.allocation_count += 1; if self.buffer >= size { self.buffer -= size; } else { @@ -54,8 +39,8 @@ impl ThreadLocalCounter { } fn remove(&mut self, size: usize) { - self.allocation_info.deallocations += size; - self.allocation_info.deallocation_count += 1; + self.allocation_counters.deallocations += size; + self.allocation_counters.deallocation_count += 1; self.buffer += size; if self.buffer > MAX_BUFFER { let offset = self.buffer - TARGET_BUFFER; @@ -69,6 +54,7 @@ impl ThreadLocalCounter { ALLOCATED.fetch_sub(self.buffer, Ordering::Relaxed); self.buffer = 0; } + self.allocation_counters = AllocationCounters::default(); } } @@ -80,8 +66,12 @@ pub fn get() -> usize { ALLOCATED.load(Ordering::Relaxed) } -pub fn pop_allocations() -> AllocationInfo { - with_local_counter(|local| std::mem::take(&mut local.allocation_info)) +pub fn allocation_counters() -> AllocationCounters { + with_local_counter(|local| local.allocation_counters.clone()) +} + +pub fn reset_allocation_counters(start: AllocationCounters) { + with_local_counter(|local| local.allocation_counters = start); } fn with_local_counter(f: impl FnOnce(&mut ThreadLocalCounter) -> T) -> T { diff --git a/crates/turbo-tasks-malloc/src/lib.rs b/crates/turbo-tasks-malloc/src/lib.rs index 768aa0333e89b..5fa6cc4c7d7cf 100644 --- a/crates/turbo-tasks-malloc/src/lib.rs +++ b/crates/turbo-tasks-malloc/src/lib.rs @@ -1,9 +1,50 @@ mod counter; -use std::alloc::{GlobalAlloc, Layout}; +use std::{ + alloc::{GlobalAlloc, Layout}, + marker::PhantomData, +}; use self::counter::{add, flush, get, remove}; +#[derive(Default, Clone, Debug)] +pub struct AllocationInfo { + pub allocations: usize, + pub deallocations: usize, + pub allocation_count: usize, + pub deallocation_count: usize, +} + +impl AllocationInfo { + pub fn is_empty(&self) -> bool { + self.allocations == 0 + && self.deallocations == 0 + && self.allocation_count == 0 + && self.deallocation_count == 0 + } +} + +#[derive(Default, Clone, Debug)] +pub struct AllocationCounters { + pub allocations: usize, + pub deallocations: usize, + pub allocation_count: usize, + pub deallocation_count: usize, + _not_send: PhantomData<*mut ()>, +} + +impl AllocationCounters { + pub fn until_now(&self) -> AllocationInfo { + let new = TurboMalloc::allocation_counters(); + AllocationInfo { + allocations: new.allocations - self.allocations, + deallocations: new.deallocations - self.deallocations, + allocation_count: new.allocation_count - self.allocation_count, + deallocation_count: new.deallocation_count - self.deallocation_count, + } + } +} + /// Turbo's preferred global allocator. This is a new type instead of a type /// alias because you can't use type aliases to instantiate unit types (E0423). pub struct TurboMalloc; @@ -17,8 +58,12 @@ impl TurboMalloc { flush(); } - pub fn pop_allocations() -> self::counter::AllocationInfo { - self::counter::pop_allocations() + pub fn allocation_counters() -> AllocationCounters { + self::counter::allocation_counters() + } + + pub fn reset_allocation_counters(start: AllocationCounters) { + self::counter::reset_allocation_counters(start); } } @@ -42,7 +87,7 @@ unsafe impl GlobalAlloc for TurboMalloc { unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { let ret = mimalloc::MiMalloc.alloc_zeroed(layout); - if ret.is_null() { + if !ret.is_null() { add(layout.size()); } ret @@ -82,7 +127,7 @@ unsafe impl GlobalAlloc for TurboMalloc { unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { let ret = std::alloc::System.alloc_zeroed(layout); - if ret.is_null() { + if !ret.is_null() { add(layout.size()); } ret diff --git a/crates/turbo-tasks-memory/Cargo.toml b/crates/turbo-tasks-memory/Cargo.toml index ae1acec5a021e..d7a615371236e 100644 --- a/crates/turbo-tasks-memory/Cargo.toml +++ b/crates/turbo-tasks-memory/Cargo.toml @@ -17,6 +17,7 @@ anyhow = { workspace = true } auto-hash-map = { workspace = true } concurrent-queue = { workspace = true } dashmap = { workspace = true } +indexmap = { workspace = true } nohash-hasher = { workspace = true } num_cpus = "1.13.1" once_cell = { workspace = true } @@ -33,8 +34,10 @@ turbo-tasks-malloc = { workspace = true, default-features = false } [dev-dependencies] criterion = { workspace = true, features = ["async_tokio"] } -indexmap = { workspace = true } lazy_static = { workspace = true } +loom = "0.7.2" +rand = { workspace = true, features = ["small_rng"] } +rstest = { workspace = true } serde = { workspace = true } tokio = { workspace = true, features = ["full"] } turbo-tasks-testing = { workspace = true } diff --git a/crates/turbo-tasks-memory/src/aggregation/aggregation_data.rs b/crates/turbo-tasks-memory/src/aggregation/aggregation_data.rs new file mode 100644 index 0000000000000..fd95e982094a3 --- /dev/null +++ b/crates/turbo-tasks-memory/src/aggregation/aggregation_data.rs @@ -0,0 +1,83 @@ +use std::ops::{Deref, DerefMut}; + +use super::{ + increase_aggregation_number_internal, AggregationContext, AggregationNode, AggregationNodeGuard, +}; +use crate::aggregation::{balance_queue::BalanceQueue, increase::IncreaseReason}; + +/// Gives an reference to the aggregated data for a given item. This will +/// convert the item to a fully aggregated node. +pub fn aggregation_data<'l, C>( + ctx: &'l C, + node_id: &C::NodeRef, +) -> AggregationDataGuard> +where + C: AggregationContext + 'l, +{ + let guard = ctx.node(node_id); + if guard.aggregation_number() == u32::MAX { + AggregationDataGuard { guard } + } else { + let mut balance_queue = BalanceQueue::new(); + increase_aggregation_number_internal( + ctx, + &mut balance_queue, + guard, + node_id, + u32::MAX, + u32::MAX, + IncreaseReason::AggregationData, + ); + balance_queue.process(ctx); + let guard = ctx.node(node_id); + debug_assert!(guard.aggregation_number() == u32::MAX); + AggregationDataGuard { guard } + } +} + +/// Converted the given node to a fully aggregated node. To make the next call +/// to `aggregation_data` instant. +pub fn prepare_aggregation_data(ctx: &C, node_id: &C::NodeRef) { + let mut balance_queue = BalanceQueue::new(); + increase_aggregation_number_internal( + ctx, + &mut balance_queue, + ctx.node(node_id), + node_id, + u32::MAX, + u32::MAX, + IncreaseReason::AggregationData, + ); + balance_queue.process(ctx); +} + +/// A reference to the aggregated data of a node. This holds a lock to the node. +pub struct AggregationDataGuard { + guard: G, +} + +impl AggregationDataGuard { + pub fn into_inner(self) -> G { + self.guard + } +} + +impl Deref for AggregationDataGuard { + type Target = G::Data; + + fn deref(&self) -> &Self::Target { + match &*self.guard { + AggregationNode::Leaf { .. } => unreachable!(), + AggregationNode::Aggegating(aggregating) => &aggregating.data, + } + } +} + +impl DerefMut for AggregationDataGuard { + fn deref_mut(&mut self) -> &mut Self::Target { + match &mut *self.guard { + AggregationNode::Leaf { .. } => unreachable!(), + AggregationNode::Aggegating(aggregating) => &mut aggregating.data, + } + } +} diff --git a/crates/turbo-tasks-memory/src/aggregation/balance_edge.rs b/crates/turbo-tasks-memory/src/aggregation/balance_edge.rs new file mode 100644 index 0000000000000..ee968cd3228d6 --- /dev/null +++ b/crates/turbo-tasks-memory/src/aggregation/balance_edge.rs @@ -0,0 +1,208 @@ +use std::cmp::Ordering; + +use super::{ + balance_queue::BalanceQueue, + followers::{ + add_follower_count, remove_follower_count, remove_positive_follower_count, + RemovePositveFollowerCountResult, + }, + in_progress::is_in_progress, + increase::IncreaseReason, + increase_aggregation_number_internal, + uppers::{ + add_upper_count, remove_positive_upper_count, remove_upper_count, + RemovePositiveUpperCountResult, + }, + AggregationContext, AggregationNode, +}; + +// Migrated followers to uppers or uppers to followers depending on the +// aggregation numbers of the nodes involved in the edge. Might increase targets +// aggregation number if they are equal. +pub(super) fn balance_edge( + ctx: &C, + balance_queue: &mut BalanceQueue, + upper_id: &C::NodeRef, + mut upper_aggregation_number: u32, + target_id: &C::NodeRef, + mut target_aggregation_number: u32, +) -> (u32, u32) { + // too many uppers on target + let mut extra_uppers = 0; + // too many followers on upper + let mut extra_followers = 0; + // The last info about uppers + let mut uppers_count: Option = None; + // The last info about followers + let mut followers_count = None; + + loop { + let root = upper_aggregation_number == u32::MAX || target_aggregation_number == u32::MAX; + let order = if root { + Ordering::Greater + } else { + upper_aggregation_number.cmp(&target_aggregation_number) + }; + match order { + Ordering::Equal => { + // we probably want to increase the aggregation number of target + let upper = ctx.node(upper_id); + upper_aggregation_number = upper.aggregation_number(); + drop(upper); + if upper_aggregation_number != u32::MAX + && upper_aggregation_number == target_aggregation_number + { + let target = ctx.node(target_id); + target_aggregation_number = target.aggregation_number(); + if upper_aggregation_number == target_aggregation_number { + // increase target aggregation number + increase_aggregation_number_internal( + ctx, + balance_queue, + target, + target_id, + target_aggregation_number + 1, + target_aggregation_number + 1, + IncreaseReason::EqualAggregationNumberOnBalance, + ); + } + } + } + Ordering::Less => { + // target should probably be a follower of upper + if uppers_count.map_or(false, |count| count <= 0) { + // We already removed all uppers, maybe too many + break; + } else if extra_followers == 0 { + let upper = ctx.node(upper_id); + upper_aggregation_number = upper.aggregation_number(); + if upper_aggregation_number < target_aggregation_number { + // target should be a follower of upper + // add some extra followers + let count = uppers_count.unwrap_or(1) as usize; + extra_followers += count; + followers_count = Some(add_follower_count( + ctx, + balance_queue, + upper, + upper_id, + target_id, + count, + true, + )); + } + } else { + // we already have extra followers, remove some uppers to balance + let count = extra_followers + extra_uppers; + let target = ctx.node(target_id); + if is_in_progress(ctx, upper_id) { + drop(target); + let mut upper = ctx.node(upper_id); + if is_in_progress(ctx, upper_id) { + let AggregationNode::Aggegating(aggregating) = &mut *upper else { + unreachable!(); + }; + aggregating.enqueued_balancing.push(( + upper_id.clone(), + upper_aggregation_number, + target_id.clone(), + target_aggregation_number, + )); + drop(upper); + // Somebody else will balance this edge + return (upper_aggregation_number, target_aggregation_number); + } + } else { + let RemovePositiveUpperCountResult { + removed_count, + remaining_count, + } = remove_positive_upper_count( + ctx, + balance_queue, + target, + upper_id, + count, + ); + decrease_numbers(removed_count, &mut extra_uppers, &mut extra_followers); + uppers_count = Some(remaining_count); + } + } + } + Ordering::Greater => { + // target should probably be an inner node of upper + if followers_count.map_or(false, |count| count <= 0) { + // We already removed all followers, maybe too many + break; + } else if extra_uppers == 0 { + let target = ctx.node(target_id); + target_aggregation_number = target.aggregation_number(); + if root || target_aggregation_number < upper_aggregation_number { + // target should be a inner node of upper + if is_in_progress(ctx, upper_id) { + drop(target); + let mut upper = ctx.node(upper_id); + if is_in_progress(ctx, upper_id) { + let AggregationNode::Aggegating(aggregating) = &mut *upper else { + unreachable!(); + }; + aggregating.enqueued_balancing.push(( + upper_id.clone(), + upper_aggregation_number, + target_id.clone(), + target_aggregation_number, + )); + drop(upper); + // Somebody else will balance this edge + return (upper_aggregation_number, target_aggregation_number); + } + } else { + // add some extra uppers + let count = followers_count.unwrap_or(1) as usize; + extra_uppers += count; + uppers_count = Some( + add_upper_count( + ctx, + balance_queue, + target, + target_id, + upper_id, + count, + true, + ) + .new_count, + ); + } + } + } else { + // we already have extra uppers, try to remove some followers to balance + let count = extra_followers + extra_uppers; + let upper = ctx.node(upper_id); + let RemovePositveFollowerCountResult { + removed_count, + remaining_count, + } = remove_positive_follower_count(ctx, balance_queue, upper, target_id, count); + decrease_numbers(removed_count, &mut extra_followers, &mut extra_uppers); + followers_count = Some(remaining_count); + } + } + } + } + if extra_followers > 0 { + let upper = ctx.node(upper_id); + remove_follower_count(ctx, balance_queue, upper, target_id, extra_followers); + } + if extra_uppers > 0 { + let target = ctx.node(target_id); + remove_upper_count(ctx, balance_queue, target, upper_id, extra_uppers); + } + (upper_aggregation_number, target_aggregation_number) +} + +fn decrease_numbers(amount: usize, a: &mut usize, b: &mut usize) { + if *a >= amount { + *a -= amount; + } else { + *b -= amount - *a; + *a = 0; + } +} diff --git a/crates/turbo-tasks-memory/src/aggregation/balance_queue.rs b/crates/turbo-tasks-memory/src/aggregation/balance_queue.rs new file mode 100644 index 0000000000000..1f11d4dd9a98d --- /dev/null +++ b/crates/turbo-tasks-memory/src/aggregation/balance_queue.rs @@ -0,0 +1,90 @@ +use std::{cmp::max, collections::HashMap, hash::Hash, mem::take}; + +use indexmap::IndexSet; + +use super::{balance_edge, AggregationContext}; + +/// Enqueued edges that need to be balanced. Deduplicates edges and keeps track +/// of aggregation numbers read during balancing. +pub struct BalanceQueue { + queue: IndexSet<(I, I)>, + aggregation_numbers: HashMap, +} + +impl BalanceQueue { + pub fn new() -> Self { + Self { + queue: IndexSet::default(), + aggregation_numbers: HashMap::default(), + } + } + + fn add_number(&mut self, id: I, number: u32) { + self.aggregation_numbers + .entry(id) + .and_modify(|n| *n = max(*n, number)) + .or_insert(number); + } + + /// Add an edge to the queue. The edge will be balanced during the next + /// call. + pub fn balance( + &mut self, + upper_id: I, + upper_aggregation_number: u32, + target_id: I, + target_aggregation_number: u32, + ) { + debug_assert!(upper_id != target_id); + self.add_number(upper_id.clone(), upper_aggregation_number); + self.add_number(target_id.clone(), target_aggregation_number); + self.queue.insert((upper_id.clone(), target_id.clone())); + } + + /// Add multiple edges to the queue. The edges will be balanced during the + /// next call. + pub fn balance_all(&mut self, edges: Vec<(I, u32, I, u32)>) { + for (upper_id, upper_aggregation_number, target_id, target_aggregation_number) in edges { + self.balance( + upper_id, + upper_aggregation_number, + target_id, + target_aggregation_number, + ); + } + } + + /// Process the queue and balance all enqueued edges. + pub fn process>(mut self, ctx: &C) { + while !self.queue.is_empty() { + let queue = take(&mut self.queue); + for (upper_id, target_id) in queue { + let upper_aggregation_number = self + .aggregation_numbers + .get(&upper_id) + .copied() + .unwrap_or_default(); + let target_aggregation_number = self + .aggregation_numbers + .get(&target_id) + .copied() + .unwrap_or_default(); + + let (u, t) = balance_edge( + ctx, + &mut self, + &upper_id, + upper_aggregation_number, + &target_id, + target_aggregation_number, + ); + if u != upper_aggregation_number { + self.add_number(upper_id, u); + } + if t != target_aggregation_number { + self.add_number(target_id, t); + } + } + } + } +} diff --git a/crates/turbo-tasks-memory/src/aggregation/change.rs b/crates/turbo-tasks-memory/src/aggregation/change.rs new file mode 100644 index 0000000000000..a0ff1eb605692 --- /dev/null +++ b/crates/turbo-tasks-memory/src/aggregation/change.rs @@ -0,0 +1,108 @@ +use std::hash::Hash; + +use super::{AggegatingNode, AggregationContext, AggregationNode, PreparedOperation, StackVec}; + +impl AggregationNode { + /// Prepares to apply a change to a node. Changes will be propagated to all + /// upper nodes. + #[must_use] + pub fn apply_change>( + &mut self, + ctx: &C, + change: C::DataChange, + ) -> Option> { + match self { + AggregationNode::Leaf { uppers, .. } => (!uppers.is_empty()).then(|| PreparedChange { + uppers: uppers.iter().cloned().collect::>(), + change, + }), + AggregationNode::Aggegating(aggegating) => { + let AggegatingNode { data, uppers, .. } = &mut **aggegating; + let change = ctx.apply_change(data, &change); + if uppers.is_empty() { + None + } else { + change.map(|change| PreparedChange { + uppers: uppers.iter().cloned().collect::>(), + change, + }) + } + } + } + } + + /// Prepares to apply a change to a node. Changes will be propagated to all + /// upper nodes. + #[must_use] + pub fn apply_change_ref<'l, C: AggregationContext>( + &mut self, + ctx: &C, + change: &'l C::DataChange, + ) -> Option> { + match self { + AggregationNode::Leaf { uppers, .. } => { + (!uppers.is_empty()).then(|| PreparedChangeRef::Borrowed { + uppers: uppers.iter().cloned().collect::>(), + change, + }) + } + AggregationNode::Aggegating(aggegating) => { + let AggegatingNode { data, uppers, .. } = &mut **aggegating; + let change = ctx.apply_change(data, change); + if uppers.is_empty() { + None + } else { + change.map(|change| PreparedChangeRef::Owned { + uppers: uppers.iter().cloned().collect::>(), + change, + }) + } + } + } + } +} + +/// A prepared `apply_change` operation. +pub struct PreparedChange { + uppers: StackVec, + change: C::DataChange, +} + +impl PreparedOperation for PreparedChange { + type Result = (); + fn apply(self, ctx: &C) { + let prepared = self + .uppers + .into_iter() + .filter_map(|upper_id| ctx.node(&upper_id).apply_change_ref(ctx, &self.change)) + .collect::>(); + prepared.apply(ctx); + } +} + +/// A prepared `apply_change_ref` operation. +pub enum PreparedChangeRef<'l, C: AggregationContext> { + Borrowed { + uppers: StackVec, + change: &'l C::DataChange, + }, + Owned { + uppers: StackVec, + change: C::DataChange, + }, +} + +impl<'l, C: AggregationContext> PreparedOperation for PreparedChangeRef<'l, C> { + type Result = (); + fn apply(self, ctx: &C) { + let (uppers, change) = match self { + PreparedChangeRef::Borrowed { uppers, change } => (uppers, change), + PreparedChangeRef::Owned { uppers, ref change } => (uppers, change), + }; + let prepared = uppers + .into_iter() + .filter_map(|upper_id| ctx.node(&upper_id).apply_change_ref(ctx, change)) + .collect::>(); + prepared.apply(ctx); + } +} diff --git a/crates/turbo-tasks-memory/src/aggregation/followers.rs b/crates/turbo-tasks-memory/src/aggregation/followers.rs new file mode 100644 index 0000000000000..f9f2f410ee125 --- /dev/null +++ b/crates/turbo-tasks-memory/src/aggregation/followers.rs @@ -0,0 +1,201 @@ +use super::{ + balance_queue::BalanceQueue, + in_progress::start_in_progress_all, + notify_lost_follower, notify_new_follower, + optimize::{optimize_aggregation_number_for_followers, MAX_FOLLOWERS}, + AggregationContext, AggregationNode, StackVec, +}; +use crate::count_hash_set::RemovePositiveCountResult; + +/// Add a follower to a node. Followers will be propagated to the uppers of the +/// node. +pub fn add_follower( + ctx: &C, + balance_queue: &mut BalanceQueue, + mut node: C::Guard<'_>, + node_id: &C::NodeRef, + follower_id: &C::NodeRef, + already_optimizing_for_node: bool, +) -> usize { + let AggregationNode::Aggegating(aggregating) = &mut *node else { + unreachable!(); + }; + if aggregating.followers.add_clonable(follower_id) { + on_added( + ctx, + balance_queue, + node, + node_id, + follower_id, + already_optimizing_for_node, + ) + } else { + 0 + } +} + +/// Handle the addition of a follower to a node. This function is called after +/// the follower has been added to the node. +pub fn on_added( + ctx: &C, + balance_queue: &mut BalanceQueue, + mut node: C::Guard<'_>, + node_id: &C::NodeRef, + follower_id: &C::NodeRef, + already_optimizing_for_node: bool, +) -> usize { + let AggregationNode::Aggegating(aggregating) = &mut *node else { + unreachable!(); + }; + let followers_len = aggregating.followers.len(); + let optimize = (!already_optimizing_for_node + && followers_len > MAX_FOLLOWERS + && (followers_len - MAX_FOLLOWERS).count_ones() == 1) + .then(|| { + aggregating + .followers + .iter() + .cloned() + .collect::>() + }); + let uppers = aggregating.uppers.iter().cloned().collect::>(); + start_in_progress_all(ctx, &uppers); + drop(node); + + let mut optimizing = false; + + if let Some(followers) = optimize { + optimizing = optimize_aggregation_number_for_followers( + ctx, + balance_queue, + node_id, + followers, + false, + ); + } + + let mut affected_nodes = uppers.len(); + for upper_id in uppers { + affected_nodes += notify_new_follower( + ctx, + balance_queue, + ctx.node(&upper_id), + &upper_id, + follower_id, + optimizing, + ); + } + affected_nodes +} + +/// Add a follower to a node with a count. Followers will be propagated to the +/// uppers of the node. +pub fn add_follower_count( + ctx: &C, + balance_queue: &mut BalanceQueue, + mut node: C::Guard<'_>, + node_id: &C::NodeRef, + follower_id: &C::NodeRef, + follower_count: usize, + already_optimizing_for_node: bool, +) -> isize { + let AggregationNode::Aggegating(aggregating) = &mut *node else { + unreachable!(); + }; + if aggregating + .followers + .add_clonable_count(follower_id, follower_count) + { + let count = aggregating.followers.get_count(follower_id); + on_added( + ctx, + balance_queue, + node, + node_id, + follower_id, + already_optimizing_for_node, + ); + count + } else { + aggregating.followers.get_count(follower_id) + } +} + +/// Remove a follower from a node. Followers will be propagated to the uppers of +/// the node. +pub fn remove_follower_count( + ctx: &C, + balance_queue: &mut BalanceQueue, + mut node: C::Guard<'_>, + follower_id: &C::NodeRef, + follower_count: usize, +) { + let AggregationNode::Aggegating(aggregating) = &mut *node else { + unreachable!(); + }; + if aggregating + .followers + .remove_clonable_count(follower_id, follower_count) + { + let uppers = aggregating.uppers.iter().cloned().collect::>(); + start_in_progress_all(ctx, &uppers); + drop(node); + for upper_id in uppers { + notify_lost_follower( + ctx, + balance_queue, + ctx.node(&upper_id), + &upper_id, + follower_id, + ); + } + } +} + +pub struct RemovePositveFollowerCountResult { + /// The amount of followers that have been removed. + pub removed_count: usize, + /// The amount of followers that are remaining. Might be negative. + pub remaining_count: isize, +} + +/// Remove a positive count of a follower from a node. Negative counts will not +/// be increased. The function returns how much of the count has been removed +/// and whats remaining. Followers will be propagated to the uppers of the node. +pub fn remove_positive_follower_count( + ctx: &C, + balance_queue: &mut BalanceQueue, + mut node: C::Guard<'_>, + follower_id: &C::NodeRef, + follower_count: usize, +) -> RemovePositveFollowerCountResult { + let AggregationNode::Aggegating(aggregating) = &mut *node else { + unreachable!(); + }; + let RemovePositiveCountResult { + removed, + removed_count, + count, + } = aggregating + .followers + .remove_positive_clonable_count(follower_id, follower_count); + + if removed { + let uppers = aggregating.uppers.iter().cloned().collect::>(); + start_in_progress_all(ctx, &uppers); + drop(node); + for upper_id in uppers { + notify_lost_follower( + ctx, + balance_queue, + ctx.node(&upper_id), + &upper_id, + follower_id, + ); + } + } + RemovePositveFollowerCountResult { + removed_count, + remaining_count: count, + } +} diff --git a/crates/turbo-tasks-memory/src/aggregation/in_progress.rs b/crates/turbo-tasks-memory/src/aggregation/in_progress.rs new file mode 100644 index 0000000000000..1dbb080630c3e --- /dev/null +++ b/crates/turbo-tasks-memory/src/aggregation/in_progress.rs @@ -0,0 +1,75 @@ +use std::{hash::Hash, mem::take}; + +use super::{balance_queue::BalanceQueue, AggregationContext, AggregationNode, StackVec}; + +impl AggregationNode { + /// Finishes an in progress operation. This might enqueue balancing + /// operations when they weren't possible due to the in progress operation. + pub(super) fn finish_in_progress>( + &mut self, + ctx: &C, + balance_queue: &mut BalanceQueue, + node_id: &I, + ) { + let value = ctx + .atomic_in_progress_counter(node_id) + .fetch_sub(1, std::sync::atomic::Ordering::AcqRel); + debug_assert!(value > 0); + if value == 1 { + if let AggregationNode::Aggegating(aggegating) = &mut *self { + balance_queue.balance_all(take(&mut aggegating.enqueued_balancing)) + } + } + } +} + +/// Finishes an in progress operation. This might enqueue balancing +/// operations when they weren't possible due to the in progress operation. +/// This version doesn't require a node guard. +pub fn finish_in_progress_without_node( + ctx: &C, + balance_queue: &mut BalanceQueue, + node_id: &C::NodeRef, +) { + let value = ctx + .atomic_in_progress_counter(node_id) + .fetch_sub(1, std::sync::atomic::Ordering::AcqRel); + debug_assert!(value > 0); + if value == 1 { + let mut node = ctx.node(node_id); + if let AggregationNode::Aggegating(aggegating) = &mut *node { + balance_queue.balance_all(take(&mut aggegating.enqueued_balancing)) + } + } +} + +/// Starts an in progress operation for all nodes in the list. +pub fn start_in_progress_all(ctx: &C, node_ids: &StackVec) { + for node_id in node_ids { + start_in_progress(ctx, node_id); + } +} + +/// Starts an in progress operation for a node. +pub fn start_in_progress(ctx: &C, node_id: &C::NodeRef) { + start_in_progress_count(ctx, node_id, 1); +} + +/// Starts multiple in progress operations for a node. +pub fn start_in_progress_count(ctx: &C, node_id: &C::NodeRef, count: u32) { + if count == 0 { + return; + } + ctx.atomic_in_progress_counter(node_id) + .fetch_add(count, std::sync::atomic::Ordering::Release); +} + +/// Checks if there is an in progress operation for a node. +/// It doesn't require a lock, but should run under a lock of the node or a +/// follower/inner node. +pub fn is_in_progress(ctx: &C, node_id: &C::NodeRef) -> bool { + let counter = ctx + .atomic_in_progress_counter(node_id) + .load(std::sync::atomic::Ordering::Acquire); + counter > 0 +} diff --git a/crates/turbo-tasks-memory/src/aggregation/increase.rs b/crates/turbo-tasks-memory/src/aggregation/increase.rs new file mode 100644 index 0000000000000..9288d34e944e5 --- /dev/null +++ b/crates/turbo-tasks-memory/src/aggregation/increase.rs @@ -0,0 +1,344 @@ +use std::{hash::Hash, mem::take}; + +use super::{ + balance_queue::BalanceQueue, AggegatingNode, AggregationContext, AggregationNode, + AggregationNodeGuard, PreparedInternalOperation, PreparedOperation, StackVec, +}; +pub(super) const LEAF_NUMBER: u32 = 64; + +#[derive(Debug)] +pub enum IncreaseReason { + Upgraded, + AggregationData, + EqualAggregationNumberOnBalance, + EqualAggregationNumberOnNewFollower, + OptimizeForUppers, + OptimizeForFollowers, + LeafEdge, + LeafEdgeAfterIncrease, + #[cfg(test)] + Test, +} + +impl AggregationNode { + /// Increase the aggregation number of a node. This might temporarily + /// violate the graph invariants between uppers and followers of that node. + /// Therefore a balancing operation is enqueued to restore the invariants. + /// The actual change to the aggregation number is applied in the prepared + /// operation after checking all upper nodes aggregation numbers. + #[must_use] + pub(super) fn increase_aggregation_number_internal< + C: AggregationContext, + >( + &mut self, + _ctx: &C, + node_id: &C::NodeRef, + min_aggregation_number: u32, + target_aggregation_number: u32, + reason: IncreaseReason, + ) -> Option> { + if self.aggregation_number() >= min_aggregation_number { + return None; + } + Some(PreparedInternalIncreaseAggregationNumber::Lazy { + node_id: node_id.clone(), + uppers: self.uppers_mut().iter().cloned().collect(), + min_aggregation_number, + target_aggregation_number, + reason, + }) + } + + /// Increase the aggregation number of a node. This is only for testing + /// proposes. + #[cfg(test)] + pub fn increase_aggregation_number>( + &mut self, + _ctx: &C, + node_id: &C::NodeRef, + new_aggregation_number: u32, + ) -> Option> { + self.increase_aggregation_number_internal( + _ctx, + node_id, + new_aggregation_number, + new_aggregation_number, + IncreaseReason::Test, + ) + .map(PreparedIncreaseAggregationNumber) + } +} + +/// Increase the aggregation number of a node directly. This might temporarily +/// violate the graph invariants between uppers and followers of that node. +/// Therefore a balancing operation is enqueued to restore the invariants. +/// The actual change to the aggregation number is applied directly without +/// checking the upper nodes. +#[must_use] +pub(super) fn increase_aggregation_number_immediately( + _ctx: &C, + node: &mut C::Guard<'_>, + node_id: C::NodeRef, + min_aggregation_number: u32, + target_aggregation_number: u32, + reason: IncreaseReason, +) -> Option> { + if node.aggregation_number() >= min_aggregation_number { + return None; + } + + let _span = tracing::trace_span!( + "increase_aggregation_number_immediately", + reason = debug(&reason) + ) + .entered(); + let children = matches!(**node, AggregationNode::Leaf { .. }) + .then(|| node.children().collect::>()); + match &mut **node { + AggregationNode::Leaf { + aggregation_number, + uppers, + } => { + let children = children.unwrap(); + if target_aggregation_number < LEAF_NUMBER { + *aggregation_number = target_aggregation_number as u8; + Some(PreparedInternalIncreaseAggregationNumber::Leaf { + target_aggregation_number, + children, + }) + } else { + let uppers_copy = uppers.iter().cloned().collect::>(); + // Convert to Aggregating + **node = AggregationNode::Aggegating(Box::new(AggegatingNode { + aggregation_number: target_aggregation_number, + uppers: take(uppers), + followers: children.iter().cloned().collect(), + data: node.get_initial_data(), + enqueued_balancing: Vec::new(), + })); + let followers = children; + Some(PreparedInternalIncreaseAggregationNumber::Aggregating { + node_id, + uppers: uppers_copy, + followers, + target_aggregation_number, + }) + } + } + AggregationNode::Aggegating(aggegating) => { + let AggegatingNode { + followers, + uppers, + aggregation_number, + .. + } = &mut **aggegating; + let uppers = uppers.iter().cloned().collect::>(); + let followers = followers.iter().cloned().collect(); + *aggregation_number = target_aggregation_number; + Some(PreparedInternalIncreaseAggregationNumber::Aggregating { + node_id, + uppers, + followers, + target_aggregation_number, + }) + } + } +} + +/// A prepared `increase_aggregation_number` operation. +pub enum PreparedInternalIncreaseAggregationNumber { + Lazy { + node_id: C::NodeRef, + uppers: StackVec, + min_aggregation_number: u32, + target_aggregation_number: u32, + reason: IncreaseReason, + }, + Leaf { + children: StackVec, + target_aggregation_number: u32, + }, + Aggregating { + node_id: C::NodeRef, + uppers: StackVec, + followers: StackVec, + target_aggregation_number: u32, + }, +} + +impl PreparedInternalOperation + for PreparedInternalIncreaseAggregationNumber +{ + type Result = (); + fn apply(self, ctx: &C, balance_queue: &mut BalanceQueue) { + match self { + PreparedInternalIncreaseAggregationNumber::Lazy { + min_aggregation_number, + mut target_aggregation_number, + node_id, + uppers, + reason, + } => { + let mut need_to_run = true; + while need_to_run { + need_to_run = false; + let mut max = 0; + for upper_id in &uppers { + let upper = ctx.node(upper_id); + let aggregation_number = upper.aggregation_number(); + if aggregation_number != u32::MAX { + if aggregation_number > max { + max = aggregation_number; + } + if aggregation_number == target_aggregation_number { + target_aggregation_number += 1; + if max >= target_aggregation_number { + need_to_run = true; + } + } + } + } + } + drop(uppers); + let mut node = ctx.node(&node_id); + if node.aggregation_number() >= min_aggregation_number { + return; + } + let _span = + tracing::trace_span!("increase_aggregation_number", reason = debug(&reason)) + .entered(); + let children = matches!(*node, AggregationNode::Leaf { .. }) + .then(|| node.children().collect::>()); + let (uppers, followers) = match &mut *node { + AggregationNode::Leaf { + aggregation_number, + uppers, + } => { + let children = children.unwrap(); + if target_aggregation_number < LEAF_NUMBER { + *aggregation_number = target_aggregation_number as u8; + drop(node); + for child_id in children { + increase_aggregation_number_internal( + ctx, + balance_queue, + ctx.node(&child_id), + &child_id, + target_aggregation_number + 1, + target_aggregation_number + 1, + IncreaseReason::LeafEdgeAfterIncrease, + ); + } + return; + } else { + let uppers_copy = uppers.iter().cloned().collect::>(); + // Convert to Aggregating + *node = AggregationNode::Aggegating(Box::new(AggegatingNode { + aggregation_number: target_aggregation_number, + uppers: take(uppers), + followers: children.iter().cloned().collect(), + data: node.get_initial_data(), + enqueued_balancing: Vec::new(), + })); + let followers = children; + drop(node); + (uppers_copy, followers) + } + } + AggregationNode::Aggegating(aggegating) => { + let AggegatingNode { + followers, + uppers, + aggregation_number, + .. + } = &mut **aggegating; + let uppers = uppers.iter().cloned().collect::>(); + let followers = followers.iter().cloned().collect(); + *aggregation_number = target_aggregation_number; + drop(node); + (uppers, followers) + } + }; + for follower_id in followers { + balance_queue.balance( + node_id.clone(), + target_aggregation_number, + follower_id, + 0, + ); + } + for upper_id in uppers { + balance_queue.balance(upper_id, 0, node_id.clone(), target_aggregation_number); + } + } + PreparedInternalIncreaseAggregationNumber::Leaf { + children, + target_aggregation_number, + } => { + for child_id in children { + increase_aggregation_number_internal( + ctx, + balance_queue, + ctx.node(&child_id), + &child_id, + target_aggregation_number + 1, + target_aggregation_number + 1, + IncreaseReason::LeafEdgeAfterIncrease, + ); + } + } + PreparedInternalIncreaseAggregationNumber::Aggregating { + node_id, + uppers, + followers, + target_aggregation_number, + } => { + for follower_id in followers { + balance_queue.balance( + node_id.clone(), + target_aggregation_number, + follower_id, + 0, + ); + } + for upper_id in uppers { + balance_queue.balance(upper_id, 0, node_id.clone(), target_aggregation_number); + } + } + } + } +} + +pub fn increase_aggregation_number_internal( + ctx: &C, + balance_queue: &mut BalanceQueue, + mut node: C::Guard<'_>, + node_id: &C::NodeRef, + min_aggregation_number: u32, + target_aggregation_number: u32, + reason: IncreaseReason, +) { + let prepared = node.increase_aggregation_number_internal( + ctx, + node_id, + min_aggregation_number, + target_aggregation_number, + reason, + ); + drop(node); + prepared.apply(ctx, balance_queue); +} + +/// A prepared `increase_aggregation_number` operation. +pub struct PreparedIncreaseAggregationNumber( + PreparedInternalIncreaseAggregationNumber, +); + +impl PreparedOperation for PreparedIncreaseAggregationNumber { + type Result = (); + fn apply(self, ctx: &C) { + let mut balance_queue = BalanceQueue::new(); + self.0.apply(ctx, &mut balance_queue); + balance_queue.process(ctx); + } +} diff --git a/crates/turbo-tasks-memory/src/aggregation/loom_tests.rs b/crates/turbo-tasks-memory/src/aggregation/loom_tests.rs new file mode 100644 index 0000000000000..3958f1e966414 --- /dev/null +++ b/crates/turbo-tasks-memory/src/aggregation/loom_tests.rs @@ -0,0 +1,268 @@ +use std::{ + fmt::Debug, + hash::Hash, + ops::{Deref, DerefMut}, + sync::{atomic::AtomicU32, Arc}, +}; + +use loom::{ + sync::{Mutex, MutexGuard}, + thread, +}; +use nohash_hasher::IsEnabled; +use rand::{rngs::SmallRng, Rng, SeedableRng}; +use ref_cast::RefCast; +use rstest::*; + +use super::{ + aggregation_data, handle_new_edge, AggregationContext, AggregationNode, AggregationNodeGuard, + PreparedOperation, +}; + +struct Node { + atomic: AtomicU32, + inner: Mutex, +} + +impl Node { + fn new(value: u32) -> Arc { + Arc::new(Node { + atomic: AtomicU32::new(0), + inner: Mutex::new(NodeInner { + children: Vec::new(), + aggregation_node: AggregationNode::new(), + value, + }), + }) + } + + fn add_child(self: &Arc, aggregation_context: &NodeAggregationContext, child: Arc) { + let mut guard = self.inner.lock().unwrap(); + guard.children.push(child.clone()); + let number_of_children = guard.children.len(); + let mut guard = unsafe { NodeGuard::new(guard, self.clone()) }; + let prepared = handle_new_edge( + aggregation_context, + &mut guard, + &NodeRef(self.clone()), + &NodeRef(child), + number_of_children, + ); + drop(guard); + prepared.apply(aggregation_context); + } +} + +#[derive(Copy, Clone)] +struct Change {} + +struct NodeInner { + children: Vec>, + aggregation_node: AggregationNode, + value: u32, +} + +struct NodeAggregationContext {} + +#[derive(Clone, RefCast)] +#[repr(transparent)] +struct NodeRef(Arc); + +impl Debug for NodeRef { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "NodeRef({})", self.0.inner.lock().unwrap().value) + } +} + +impl Hash for NodeRef { + fn hash(&self, state: &mut H) { + Arc::as_ptr(&self.0).hash(state); + } +} + +impl IsEnabled for NodeRef {} + +impl PartialEq for NodeRef { + fn eq(&self, other: &Self) -> bool { + Arc::ptr_eq(&self.0, &other.0) + } +} + +impl Eq for NodeRef {} + +struct NodeGuard { + guard: MutexGuard<'static, NodeInner>, + // This field is important to keep the node alive + #[allow(dead_code)] + node: Arc, +} + +impl NodeGuard { + unsafe fn new(guard: MutexGuard<'_, NodeInner>, node: Arc) -> Self { + NodeGuard { + guard: unsafe { std::mem::transmute(guard) }, + node, + } + } +} + +impl Deref for NodeGuard { + type Target = AggregationNode; + + fn deref(&self) -> &Self::Target { + &self.guard.aggregation_node + } +} + +impl DerefMut for NodeGuard { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.guard.aggregation_node + } +} + +impl AggregationNodeGuard for NodeGuard { + type Data = Aggregated; + type NodeRef = NodeRef; + type DataChange = Change; + type ChildrenIter<'a> = impl Iterator + 'a; + + fn children(&self) -> Self::ChildrenIter<'_> { + self.guard + .children + .iter() + .map(|child| NodeRef(child.clone())) + } + + fn get_remove_change(&self) -> Option { + None + } + + fn get_add_change(&self) -> Option { + None + } + + fn get_initial_data(&self) -> Self::Data { + Aggregated {} + } +} + +impl AggregationContext for NodeAggregationContext { + type Guard<'l> = NodeGuard where Self: 'l; + type Data = Aggregated; + type NodeRef = NodeRef; + type DataChange = Change; + + fn node<'b>(&'b self, reference: &Self::NodeRef) -> Self::Guard<'b> { + let r = reference.0.clone(); + let guard = reference.0.inner.lock().unwrap(); + unsafe { NodeGuard::new(guard, r) } + } + + fn atomic_in_progress_counter<'l>(&self, id: &'l NodeRef) -> &'l AtomicU32 + where + Self: 'l, + { + &id.0.atomic + } + + fn apply_change(&self, _data: &mut Aggregated, _change: &Change) -> Option { + None + } + + fn data_to_add_change(&self, _data: &Self::Data) -> Option { + None + } + + fn data_to_remove_change(&self, _data: &Self::Data) -> Option { + None + } +} + +#[derive(Default)] +struct Aggregated {} + +// #[test] +#[allow(dead_code)] +fn fuzzy_loom_new() { + for size in [10, 20] { + for _ in 0..1000 { + let seed = rand::random(); + println!("Seed {} Size {}", seed, size); + fuzzy_loom(seed, size); + } + } +} + +#[rstest] +#[case::a(3302552607, 10)] +// #[case::b(3629477471, 50)] +// #[case::c(1006976052, 20)] +// #[case::d(2174645157, 10)] +fn fuzzy_loom(#[case] seed: u32, #[case] count: u32) { + let mut builder = loom::model::Builder::new(); + builder.max_branches = 100000; + builder.check(move || { + loom::stop_exploring(); + thread::Builder::new() + .stack_size(80000) + .spawn(move || { + let ctx = NodeAggregationContext {}; + + let mut seed_buffer = [0; 32]; + seed_buffer[0..4].copy_from_slice(&seed.to_be_bytes()); + let mut r = SmallRng::from_seed(seed_buffer); + let mut nodes = Vec::new(); + for i in 0..count { + nodes.push(Node::new(i)); + } + aggregation_data(&ctx, &NodeRef(nodes[0].clone())); + aggregation_data(&ctx, &NodeRef(nodes[1].clone())); + + // setup graph + for _ in 0..20 { + let parent = r.gen_range(0..nodes.len() - 1); + let child = r.gen_range(parent + 1..nodes.len()); + let parent_node = nodes[parent].clone(); + let child_node = nodes[child].clone(); + parent_node.add_child(&ctx, child_node); + } + + let mut edges = Vec::new(); + for _ in 0..2 { + let parent = r.gen_range(0..nodes.len() - 1); + let child = r.gen_range(parent + 1..nodes.len()); + let parent_node = nodes[parent].clone(); + let child_node = nodes[child].clone(); + edges.push((parent_node, child_node)); + } + + let ctx = Arc::new(ctx); + + loom::explore(); + + let mut threads = Vec::new(); + + // Fancy testing + for (parent_node, child_node) in edges.iter() { + let parent_node = parent_node.clone(); + let child_node = child_node.clone(); + let ctx = ctx.clone(); + threads.push( + thread::Builder::new() + .stack_size(80000) + .spawn(move || { + parent_node.add_child(&ctx, child_node); + }) + .unwrap(), + ); + } + + for thread in threads { + thread.join().unwrap(); + } + }) + .unwrap() + .join() + .unwrap(); + }); +} diff --git a/crates/turbo-tasks-memory/src/aggregation/lost_edge.rs b/crates/turbo-tasks-memory/src/aggregation/lost_edge.rs new file mode 100644 index 0000000000000..7c95e3cbb461c --- /dev/null +++ b/crates/turbo-tasks-memory/src/aggregation/lost_edge.rs @@ -0,0 +1,115 @@ +use std::hash::Hash; + +use super::{ + balance_queue::BalanceQueue, in_progress::start_in_progress_count, + notify_lost_follower::PreparedNotifyLostFollower, AggregationContext, AggregationNode, + PreparedInternalOperation, PreparedOperation, StackVec, +}; + +impl AggregationNode { + /// Handles the loss of edges to a node. This will notify all upper nodes + /// about the new follower or add the new node as inner node. + #[must_use] + pub fn handle_lost_edges>( + &mut self, + ctx: &C, + origin_id: &C::NodeRef, + target_ids: impl IntoIterator, + ) -> Option> { + match self { + AggregationNode::Leaf { uppers, .. } => { + let uppers = uppers.iter().cloned().collect::>(); + let target_ids: StackVec<_> = target_ids.into_iter().collect(); + for upper_id in &uppers { + start_in_progress_count(ctx, upper_id, target_ids.len() as u32); + } + Some(PreparedLostEdgesInner::Leaf { uppers, target_ids }.into()) + } + AggregationNode::Aggegating(_) => { + let notify = target_ids + .into_iter() + .filter_map(|target_id| { + self.notify_lost_follower_not_in_progress(ctx, origin_id, &target_id) + }) + .collect::>(); + (!notify.is_empty()).then(|| notify.into()) + } + } + } +} + +/// A prepared `handle_lost_edges` operation. +pub struct PreparedLostEdges { + inner: PreparedLostEdgesInner, +} + +impl From> for PreparedLostEdges { + fn from(inner: PreparedLostEdgesInner) -> Self { + Self { inner } + } +} + +impl From>> for PreparedLostEdges { + fn from(notify: StackVec>) -> Self { + Self { + inner: PreparedLostEdgesInner::Aggregating { notify }, + } + } +} + +#[allow(clippy::large_enum_variant)] +enum PreparedLostEdgesInner { + Leaf { + uppers: StackVec, + target_ids: StackVec, + }, + Aggregating { + notify: StackVec>, + }, +} + +impl PreparedOperation for PreparedLostEdges { + type Result = (); + fn apply(self, ctx: &C) { + let mut balance_queue = BalanceQueue::new(); + match self.inner { + PreparedLostEdgesInner::Leaf { uppers, target_ids } => { + // TODO This could be more efficient + for upper_id in uppers { + let mut upper = ctx.node(&upper_id); + let prepared = target_ids + .iter() + .filter_map(|target_id| { + upper.notify_lost_follower( + ctx, + &mut balance_queue, + &upper_id, + target_id, + ) + }) + .collect::>(); + drop(upper); + prepared.apply(ctx, &mut balance_queue); + } + } + PreparedLostEdgesInner::Aggregating { notify } => { + notify.apply(ctx, &mut balance_queue); + } + } + balance_queue.process(ctx); + } +} + +/// Handles the loss of edges to a node. This will notify all upper nodes +/// about the new follower or add the new node as inner node. +#[cfg(test)] +pub fn handle_lost_edges( + ctx: &C, + mut origin: C::Guard<'_>, + origin_id: &C::NodeRef, + target_ids: impl IntoIterator, +) { + let p = origin.handle_lost_edges(ctx, origin_id, target_ids); + drop(origin); + p.apply(ctx); +} diff --git a/crates/turbo-tasks-memory/src/aggregation/mod.rs b/crates/turbo-tasks-memory/src/aggregation/mod.rs new file mode 100644 index 0000000000000..6658cedcb897e --- /dev/null +++ b/crates/turbo-tasks-memory/src/aggregation/mod.rs @@ -0,0 +1,235 @@ +use std::{fmt::Debug, hash::Hash, ops::DerefMut, sync::atomic::AtomicU32}; + +use smallvec::SmallVec; + +use crate::count_hash_set::CountHashSet; + +mod aggregation_data; +mod balance_edge; +mod balance_queue; +mod change; +mod followers; +mod in_progress; +mod increase; +#[cfg(test)] +mod loom_tests; +mod lost_edge; +mod new_edge; +mod notify_lost_follower; +mod notify_new_follower; +mod optimize; +mod root_query; +#[cfg(test)] +mod tests; +mod uppers; + +pub use aggregation_data::{aggregation_data, prepare_aggregation_data, AggregationDataGuard}; +use balance_edge::balance_edge; +use increase::increase_aggregation_number_internal; +pub use new_edge::handle_new_edge; +use notify_lost_follower::notify_lost_follower; +use notify_new_follower::notify_new_follower; +pub use root_query::{query_root_info, RootQuery}; + +use self::balance_queue::BalanceQueue; + +type StackVec = SmallVec<[I; 16]>; + +/// The aggregation node structure. This stores the aggregation number, the +/// aggregation edges to uppers and followers and the aggregated data. +pub enum AggregationNode { + Leaf { + aggregation_number: u8, + uppers: CountHashSet, + }, + Aggegating(Box>), +} + +impl AggregationNode { + pub fn new() -> Self { + Self::Leaf { + aggregation_number: 0, + uppers: CountHashSet::new(), + } + } +} + +/// The aggregation node structure for aggregating nodes. +pub struct AggegatingNode { + aggregation_number: u32, + uppers: CountHashSet, + followers: CountHashSet, + data: D, + enqueued_balancing: Vec<(I, u32, I, u32)>, +} + +impl AggregationNode { + /// Returns the aggregation number of the node. + pub fn aggregation_number(&self) -> u32 { + match self { + AggregationNode::Leaf { + aggregation_number, .. + } => *aggregation_number as u32, + AggregationNode::Aggegating(aggegating) => aggegating.aggregation_number, + } + } + + fn is_leaf(&self) -> bool { + matches!(self, AggregationNode::Leaf { .. }) + } + + fn uppers(&self) -> &CountHashSet { + match self { + AggregationNode::Leaf { uppers, .. } => uppers, + AggregationNode::Aggegating(aggegating) => &aggegating.uppers, + } + } + + fn uppers_mut(&mut self) -> &mut CountHashSet { + match self { + AggregationNode::Leaf { uppers, .. } => uppers, + AggregationNode::Aggegating(aggegating) => &mut aggegating.uppers, + } + } + + fn followers(&self) -> Option<&CountHashSet> { + match self { + AggregationNode::Leaf { .. } => None, + AggregationNode::Aggegating(aggegating) => Some(&aggegating.followers), + } + } +} + +/// A prepared operation. Must be applied outside of node locks. +#[must_use] +pub trait PreparedOperation { + type Result; + fn apply(self, ctx: &C) -> Self::Result; +} + +impl> PreparedOperation for Option { + type Result = Option; + fn apply(self, ctx: &C) -> Self::Result { + self.map(|prepared| prepared.apply(ctx)) + } +} + +impl> PreparedOperation for Vec { + type Result = (); + fn apply(self, ctx: &C) -> Self::Result { + for prepared in self { + prepared.apply(ctx); + } + } +} + +impl, const N: usize> PreparedOperation + for SmallVec<[T; N]> +{ + type Result = (); + fn apply(self, ctx: &C) -> Self::Result { + for prepared in self { + prepared.apply(ctx); + } + } +} + +/// A prepared internal operation. Must be applied inside of node locks and with +/// a balance queue. +#[must_use] +trait PreparedInternalOperation { + type Result; + fn apply(self, ctx: &C, balance_queue: &mut BalanceQueue) -> Self::Result; +} + +impl> PreparedInternalOperation + for Option +{ + type Result = Option; + fn apply(self, ctx: &C, balance_queue: &mut BalanceQueue) -> Self::Result { + self.map(|prepared| prepared.apply(ctx, balance_queue)) + } +} + +impl> PreparedInternalOperation + for Vec +{ + type Result = (); + fn apply(self, ctx: &C, balance_queue: &mut BalanceQueue) -> Self::Result { + for prepared in self { + prepared.apply(ctx, balance_queue); + } + } +} + +impl, const N: usize> + PreparedInternalOperation for SmallVec<[T; N]> +{ + type Result = (); + fn apply(self, ctx: &C, balance_queue: &mut BalanceQueue) -> Self::Result { + for prepared in self { + prepared.apply(ctx, balance_queue); + } + } +} + +/// Context for aggregation operations. +pub trait AggregationContext { + type NodeRef: Clone + Eq + Hash + Debug; + type Guard<'l>: AggregationNodeGuard< + NodeRef = Self::NodeRef, + Data = Self::Data, + DataChange = Self::DataChange, + > + where + Self: 'l; + type Data; + type DataChange; + + /// Gets mutable access to an item. + fn node<'l>(&'l self, id: &Self::NodeRef) -> Self::Guard<'l>; + + /// Get the atomic in progress counter for a node. + fn atomic_in_progress_counter<'l>(&self, id: &'l Self::NodeRef) -> &'l AtomicU32 + where + Self: 'l; + + /// Apply a changeset to an aggregated data object. Returns a new changeset + /// that should be applied to the next aggregation level. Might return None, + /// if no change should be applied to the next level. + fn apply_change( + &self, + data: &mut Self::Data, + change: &Self::DataChange, + ) -> Option; + + /// Creates a changeset from an aggregated data object, that represents + /// adding the aggregated node to an aggregated node of the next level. + fn data_to_add_change(&self, data: &Self::Data) -> Option; + /// Creates a changeset from an aggregated data object, that represents + /// removing the aggregated node from an aggregated node of the next level. + fn data_to_remove_change(&self, data: &Self::Data) -> Option; +} + +/// A guard for a node that allows to access the aggregation node, children and +/// data. +pub trait AggregationNodeGuard: + DerefMut> +{ + type NodeRef: Clone + Eq + Hash; + type Data; + type DataChange; + + type ChildrenIter<'a>: Iterator + 'a + where + Self: 'a; + + /// Returns an iterator over the children. + fn children(&self) -> Self::ChildrenIter<'_>; + /// Returns a changeset that represents the addition of the node. + fn get_add_change(&self) -> Option; + /// Returns a changeset that represents the removal of the node. + fn get_remove_change(&self) -> Option; + /// Returns the aggregated data which contains only that node + fn get_initial_data(&self) -> Self::Data; +} diff --git a/crates/turbo-tasks-memory/src/aggregation/new_edge.rs b/crates/turbo-tasks-memory/src/aggregation/new_edge.rs new file mode 100644 index 0000000000000..306fb47a63f08 --- /dev/null +++ b/crates/turbo-tasks-memory/src/aggregation/new_edge.rs @@ -0,0 +1,173 @@ +use super::{ + balance_queue::BalanceQueue, + in_progress::start_in_progress_all, + increase::{ + increase_aggregation_number_immediately, IncreaseReason, + PreparedInternalIncreaseAggregationNumber, LEAF_NUMBER, + }, + increase_aggregation_number_internal, notify_new_follower, + notify_new_follower::PreparedNotifyNewFollower, + optimize::optimize_aggregation_number_for_uppers, + AggregationContext, AggregationNode, PreparedInternalOperation, PreparedOperation, StackVec, +}; + +const BUFFER_SPACE: u32 = 2; + +const MAX_UPPERS_TIMES_CHILDREN: usize = 32; + +const MAX_AFFECTED_NODES: usize = 4096; + +/// Handle the addition of a new edge to a node. The the edge is propagated to +/// the uppers of that node or added a inner node. +pub fn handle_new_edge( + ctx: &C, + origin: &mut C::Guard<'_>, + origin_id: &C::NodeRef, + target_id: &C::NodeRef, + number_of_children: usize, +) -> impl PreparedOperation { + match **origin { + AggregationNode::Leaf { + ref mut aggregation_number, + ref uppers, + } => { + if number_of_children.count_ones() == 1 + && (uppers.len() + 1) * number_of_children >= MAX_UPPERS_TIMES_CHILDREN + { + let uppers = uppers.iter().cloned().collect::>(); + start_in_progress_all(ctx, &uppers); + let increase = increase_aggregation_number_immediately( + ctx, + origin, + origin_id.clone(), + LEAF_NUMBER, + LEAF_NUMBER, + IncreaseReason::Upgraded, + ) + .unwrap(); + Some(PreparedNewEdge::Upgraded { + uppers, + target_id: target_id.clone(), + increase, + }) + } else { + let min_aggregation_number = *aggregation_number as u32 + 1; + let target_aggregation_number = *aggregation_number as u32 + 1 + BUFFER_SPACE; + let uppers = uppers.iter().cloned().collect::>(); + start_in_progress_all(ctx, &uppers); + Some(PreparedNewEdge::Leaf { + min_aggregation_number, + target_aggregation_number, + uppers, + target_id: target_id.clone(), + }) + } + } + AggregationNode::Aggegating(_) => origin + .notify_new_follower_not_in_progress(ctx, origin_id, target_id) + .map(|notify| PreparedNewEdge::Aggegating { + target_id: target_id.clone(), + notify, + }), + } +} + +/// A prepared `handle_new_edge` operation. +enum PreparedNewEdge { + Leaf { + min_aggregation_number: u32, + target_aggregation_number: u32, + uppers: StackVec, + target_id: C::NodeRef, + }, + Upgraded { + uppers: StackVec, + target_id: C::NodeRef, + increase: PreparedInternalIncreaseAggregationNumber, + }, + Aggegating { + notify: PreparedNotifyNewFollower, + target_id: C::NodeRef, + }, +} + +impl PreparedOperation for PreparedNewEdge { + type Result = (); + fn apply(self, ctx: &C) { + let mut balance_queue = BalanceQueue::new(); + match self { + PreparedNewEdge::Leaf { + min_aggregation_number, + target_aggregation_number, + uppers, + target_id, + } => { + increase_aggregation_number_internal( + ctx, + &mut balance_queue, + ctx.node(&target_id), + &target_id, + min_aggregation_number, + target_aggregation_number, + IncreaseReason::LeafEdge, + ); + let mut affected_nodes = 0; + for upper_id in uppers { + affected_nodes += notify_new_follower( + ctx, + &mut balance_queue, + ctx.node(&upper_id), + &upper_id, + &target_id, + false, + ); + if affected_nodes > MAX_AFFECTED_NODES { + handle_expensive_node(ctx, &mut balance_queue, &target_id); + } + } + } + PreparedNewEdge::Upgraded { + uppers, + target_id, + increase, + } => { + // Since it was added to a leaf node, we would add it to the uppers + for upper_id in uppers { + notify_new_follower( + ctx, + &mut balance_queue, + ctx.node(&upper_id), + &upper_id, + &target_id, + true, + ); + } + // The balancing will attach it to the aggregated node later + increase.apply(ctx, &mut balance_queue); + } + PreparedNewEdge::Aggegating { target_id, notify } => { + let affected_nodes = notify.apply(ctx, &mut balance_queue); + if affected_nodes > MAX_AFFECTED_NODES { + handle_expensive_node(ctx, &mut balance_queue, &target_id); + } + } + } + balance_queue.process(ctx); + } +} + +/// Called in the case when we detect that adding this node was expensive. It +/// optimizes the aggregation number of the node so it can be cheaper on the +/// next call. +fn handle_expensive_node( + ctx: &C, + balance_queue: &mut BalanceQueue, + node_id: &C::NodeRef, +) { + let _span = tracing::trace_span!("handle_expensive_node").entered(); + let node = ctx.node(node_id); + let uppers = node.uppers().iter().cloned().collect::>(); + let leaf = matches!(*node, AggregationNode::Leaf { .. }); + drop(node); + optimize_aggregation_number_for_uppers(ctx, balance_queue, node_id, leaf, uppers); +} diff --git a/crates/turbo-tasks-memory/src/aggregation/notify_lost_follower.rs b/crates/turbo-tasks-memory/src/aggregation/notify_lost_follower.rs new file mode 100644 index 0000000000000..bbddd4862ba18 --- /dev/null +++ b/crates/turbo-tasks-memory/src/aggregation/notify_lost_follower.rs @@ -0,0 +1,217 @@ +use std::{hash::Hash, thread::yield_now}; + +use super::{ + balance_queue::BalanceQueue, + in_progress::{finish_in_progress_without_node, start_in_progress, start_in_progress_all}, + AggegatingNode, AggregationContext, AggregationNode, AggregationNodeGuard, + PreparedInternalOperation, PreparedOperation, StackVec, +}; +use crate::count_hash_set::RemoveIfEntryResult; + +impl AggregationNode { + /// Called when a inner node of the upper node has lost a follower + /// It's expected that the upper node is flagged as "in progress". + pub(super) fn notify_lost_follower>( + &mut self, + ctx: &C, + balance_queue: &mut BalanceQueue, + upper_id: &C::NodeRef, + follower_id: &C::NodeRef, + ) -> Option> { + let AggregationNode::Aggegating(aggregating) = self else { + unreachable!(); + }; + match aggregating.followers.remove_if_entry(follower_id) { + RemoveIfEntryResult::PartiallyRemoved => { + self.finish_in_progress(ctx, balance_queue, upper_id); + None + } + RemoveIfEntryResult::Removed => { + let uppers = aggregating.uppers.iter().cloned().collect::>(); + start_in_progress_all(ctx, &uppers); + self.finish_in_progress(ctx, balance_queue, upper_id); + Some(PreparedNotifyLostFollower::RemovedFollower { + uppers, + follower_id: follower_id.clone(), + }) + } + RemoveIfEntryResult::NotPresent => Some(PreparedNotifyLostFollower::NotFollower { + upper_id: upper_id.clone(), + follower_id: follower_id.clone(), + }), + } + } + + /// Called when a inner node of the upper node has lost a follower. + /// It's expected that the upper node is NOT flagged as "in progress". + pub(super) fn notify_lost_follower_not_in_progress< + C: AggregationContext, + >( + &mut self, + ctx: &C, + upper_id: &C::NodeRef, + follower_id: &C::NodeRef, + ) -> Option> { + let AggregationNode::Aggegating(aggregating) = self else { + unreachable!(); + }; + match aggregating.followers.remove_if_entry(follower_id) { + RemoveIfEntryResult::PartiallyRemoved => None, + RemoveIfEntryResult::Removed => { + let uppers = aggregating.uppers.iter().cloned().collect::>(); + start_in_progress_all(ctx, &uppers); + Some(PreparedNotifyLostFollower::RemovedFollower { + uppers, + follower_id: follower_id.clone(), + }) + } + RemoveIfEntryResult::NotPresent => { + start_in_progress(ctx, upper_id); + Some(PreparedNotifyLostFollower::NotFollower { + upper_id: upper_id.clone(), + follower_id: follower_id.clone(), + }) + } + } + } +} + +/// A prepared `notify_lost_follower` operation. +pub(super) enum PreparedNotifyLostFollower { + RemovedFollower { + uppers: StackVec, + follower_id: C::NodeRef, + }, + NotFollower { + upper_id: C::NodeRef, + follower_id: C::NodeRef, + }, +} + +impl PreparedInternalOperation for PreparedNotifyLostFollower { + type Result = (); + fn apply(self, ctx: &C, balance_queue: &mut BalanceQueue) { + match self { + PreparedNotifyLostFollower::RemovedFollower { + uppers, + follower_id, + } => { + for upper_id in uppers { + notify_lost_follower( + ctx, + balance_queue, + ctx.node(&upper_id), + &upper_id, + &follower_id, + ); + } + } + PreparedNotifyLostFollower::NotFollower { + upper_id, + follower_id, + } => { + loop { + let mut follower = ctx.node(&follower_id); + match follower.uppers_mut().remove_if_entry(&upper_id) { + RemoveIfEntryResult::PartiallyRemoved => { + finish_in_progress_without_node(ctx, balance_queue, &upper_id); + drop(follower); + return; + } + RemoveIfEntryResult::Removed => { + let remove_change = get_aggregated_remove_change(ctx, &follower); + let followers = match &*follower { + AggregationNode::Leaf { .. } => { + follower.children().collect::>() + } + AggregationNode::Aggegating(aggregating) => { + let AggegatingNode { ref followers, .. } = **aggregating; + followers.iter().cloned().collect::>() + } + }; + drop(follower); + + let mut upper = ctx.node(&upper_id); + let remove_change = remove_change + .map(|remove_change| upper.apply_change(ctx, remove_change)); + let prepared = followers + .into_iter() + .filter_map(|follower_id| { + upper.notify_lost_follower_not_in_progress( + ctx, + &upper_id, + &follower_id, + ) + }) + .collect::>(); + upper.finish_in_progress(ctx, balance_queue, &upper_id); + drop(upper); + prepared.apply(ctx, balance_queue); + remove_change.apply(ctx); + return; + } + RemoveIfEntryResult::NotPresent => { + drop(follower); + let mut upper = ctx.node(&upper_id); + let AggregationNode::Aggegating(aggregating) = &mut *upper else { + unreachable!(); + }; + match aggregating.followers.remove_if_entry(&follower_id) { + RemoveIfEntryResult::PartiallyRemoved => { + upper.finish_in_progress(ctx, balance_queue, &upper_id); + return; + } + RemoveIfEntryResult::Removed => { + let uppers = + aggregating.uppers.iter().cloned().collect::>(); + start_in_progress_all(ctx, &uppers); + upper.finish_in_progress(ctx, balance_queue, &upper_id); + drop(upper); + for upper_id in uppers { + notify_lost_follower( + ctx, + balance_queue, + ctx.node(&upper_id), + &upper_id, + &follower_id, + ); + } + return; + } + RemoveIfEntryResult::NotPresent => { + drop(upper); + yield_now() + // Retry, concurrency + } + } + } + } + } + } + } + } +} + +/// Notifies the upper node that a follower has been lost. +/// It's expected that the upper node is flagged as "in progress". +pub fn notify_lost_follower( + ctx: &C, + balance_queue: &mut BalanceQueue, + mut upper: C::Guard<'_>, + upper_id: &C::NodeRef, + follower_id: &C::NodeRef, +) { + let p = upper.notify_lost_follower(ctx, balance_queue, upper_id, follower_id); + drop(upper); + p.apply(ctx, balance_queue); +} + +fn get_aggregated_remove_change( + ctx: &C, + guard: &C::Guard<'_>, +) -> Option { + match &**guard { + AggregationNode::Leaf { .. } => guard.get_remove_change(), + AggregationNode::Aggegating(aggegating) => ctx.data_to_remove_change(&aggegating.data), + } +} diff --git a/crates/turbo-tasks-memory/src/aggregation/notify_new_follower.rs b/crates/turbo-tasks-memory/src/aggregation/notify_new_follower.rs new file mode 100644 index 0000000000000..573b62b92c5c7 --- /dev/null +++ b/crates/turbo-tasks-memory/src/aggregation/notify_new_follower.rs @@ -0,0 +1,245 @@ +use std::{cmp::Ordering, hash::Hash}; + +use super::{ + balance_queue::BalanceQueue, + followers::add_follower, + in_progress::{finish_in_progress_without_node, start_in_progress}, + increase::IncreaseReason, + increase_aggregation_number_internal, + optimize::optimize_aggregation_number_for_uppers, + uppers::add_upper, + AggregationContext, AggregationNode, PreparedInternalOperation, StackVec, +}; + +const MAX_AFFECTED_NODES: usize = 4096; + +impl AggregationNode { + // Called when a inner node of the upper node has a new follower. + // It's expected that the upper node is flagged as "in progress". + pub(super) fn notify_new_follower>( + &mut self, + ctx: &C, + balance_queue: &mut BalanceQueue, + upper_id: &C::NodeRef, + follower_id: &C::NodeRef, + already_optimizing_for_upper: bool, + ) -> Option> { + let AggregationNode::Aggegating(aggregating) = self else { + unreachable!(); + }; + if aggregating.followers.add_if_entry(follower_id) { + self.finish_in_progress(ctx, balance_queue, upper_id); + None + } else { + let upper_aggregation_number = aggregating.aggregation_number; + if upper_aggregation_number == u32::MAX { + Some(PreparedNotifyNewFollower::Inner { + upper_id: upper_id.clone(), + follower_id: follower_id.clone(), + already_optimizing_for_upper, + }) + } else { + Some(PreparedNotifyNewFollower::FollowerOrInner { + upper_aggregation_number, + upper_id: upper_id.clone(), + follower_id: follower_id.clone(), + already_optimizing_for_upper, + }) + } + } + } + + // Called when a inner node of the upper node has a new follower. + // It's expected that the upper node is NOT flagged as "in progress". + pub(super) fn notify_new_follower_not_in_progress< + C: AggregationContext, + >( + &mut self, + ctx: &C, + upper_id: &C::NodeRef, + follower_id: &C::NodeRef, + ) -> Option> { + let AggregationNode::Aggegating(aggregating) = self else { + unreachable!(); + }; + if aggregating.followers.add_if_entry(follower_id) { + None + } else { + start_in_progress(ctx, upper_id); + let upper_aggregation_number = aggregating.aggregation_number; + if upper_aggregation_number == u32::MAX { + Some(PreparedNotifyNewFollower::Inner { + upper_id: upper_id.clone(), + follower_id: follower_id.clone(), + already_optimizing_for_upper: false, + }) + } else { + Some(PreparedNotifyNewFollower::FollowerOrInner { + upper_aggregation_number, + upper_id: upper_id.clone(), + follower_id: follower_id.clone(), + already_optimizing_for_upper: false, + }) + } + } + } +} + +/// A prepared `notify_new_follower` operation. +pub(super) enum PreparedNotifyNewFollower { + Inner { + upper_id: C::NodeRef, + follower_id: C::NodeRef, + already_optimizing_for_upper: bool, + }, + FollowerOrInner { + upper_aggregation_number: u32, + upper_id: C::NodeRef, + follower_id: C::NodeRef, + already_optimizing_for_upper: bool, + }, +} + +impl PreparedInternalOperation for PreparedNotifyNewFollower { + type Result = usize; + fn apply(self, ctx: &C, balance_queue: &mut BalanceQueue) -> Self::Result { + match self { + PreparedNotifyNewFollower::Inner { + upper_id, + follower_id, + already_optimizing_for_upper, + } => { + let follower = ctx.node(&follower_id); + let affected_nodes = add_upper( + ctx, + balance_queue, + follower, + &follower_id, + &upper_id, + already_optimizing_for_upper, + ); + finish_in_progress_without_node(ctx, balance_queue, &upper_id); + if !already_optimizing_for_upper && affected_nodes > MAX_AFFECTED_NODES { + let follower = ctx.node(&follower_id); + let uppers = follower.uppers().iter().cloned().collect::>(); + let leaf: bool = follower.is_leaf(); + drop(follower); + if optimize_aggregation_number_for_uppers( + ctx, + balance_queue, + &follower_id, + leaf, + uppers, + ) { + return 1; + } + } + affected_nodes + } + PreparedNotifyNewFollower::FollowerOrInner { + mut upper_aggregation_number, + upper_id, + follower_id, + already_optimizing_for_upper, + } => loop { + let follower = ctx.node(&follower_id); + let follower_aggregation_number = follower.aggregation_number(); + if follower_aggregation_number < upper_aggregation_number { + let affected_nodes = add_upper( + ctx, + balance_queue, + follower, + &follower_id, + &upper_id, + already_optimizing_for_upper, + ); + finish_in_progress_without_node(ctx, balance_queue, &upper_id); + if !already_optimizing_for_upper && affected_nodes > MAX_AFFECTED_NODES { + let follower = ctx.node(&follower_id); + let uppers = follower.uppers().iter().cloned().collect::>(); + let leaf = follower.is_leaf(); + drop(follower); + if optimize_aggregation_number_for_uppers( + ctx, + balance_queue, + &follower_id, + leaf, + uppers, + ) { + return 1; + } + } + return affected_nodes; + } else { + drop(follower); + let mut upper = ctx.node(&upper_id); + let AggregationNode::Aggegating(aggregating) = &mut *upper else { + unreachable!(); + }; + upper_aggregation_number = aggregating.aggregation_number; + if upper_aggregation_number == u32::MAX { + // retry, concurrency + } else { + match follower_aggregation_number.cmp(&upper_aggregation_number) { + Ordering::Less => { + // retry, concurrency + } + Ordering::Equal => { + drop(upper); + let follower = ctx.node(&follower_id); + let follower_aggregation_number = follower.aggregation_number(); + if follower_aggregation_number == upper_aggregation_number { + increase_aggregation_number_internal( + ctx, + balance_queue, + follower, + &follower_id, + upper_aggregation_number + 1, + upper_aggregation_number + 1, + IncreaseReason::EqualAggregationNumberOnNewFollower, + ); + // retry + } else { + // retry, concurrency + } + } + Ordering::Greater => { + upper.finish_in_progress(ctx, balance_queue, &upper_id); + return add_follower( + ctx, + balance_queue, + upper, + &upper_id, + &follower_id, + already_optimizing_for_upper, + ); + } + } + } + } + }, + } + } +} + +/// Notifies the upper node that it has a new follower. +/// Returns the number of affected nodes. +/// The upper node is expected to be flagged as "in progress". +pub fn notify_new_follower( + ctx: &C, + balance_queue: &mut BalanceQueue, + mut upper: C::Guard<'_>, + upper_id: &C::NodeRef, + follower_id: &C::NodeRef, + already_optimizing_for_upper: bool, +) -> usize { + let p = upper.notify_new_follower( + ctx, + balance_queue, + upper_id, + follower_id, + already_optimizing_for_upper, + ); + drop(upper); + p.apply(ctx, balance_queue).unwrap_or_default() +} diff --git a/crates/turbo-tasks-memory/src/aggregation/optimize.rs b/crates/turbo-tasks-memory/src/aggregation/optimize.rs new file mode 100644 index 0000000000000..8ca45a882a35d --- /dev/null +++ b/crates/turbo-tasks-memory/src/aggregation/optimize.rs @@ -0,0 +1,146 @@ +use tracing::Level; + +use super::{ + balance_queue::BalanceQueue, + increase::{increase_aggregation_number_internal, IncreaseReason, LEAF_NUMBER}, + AggregationContext, StackVec, +}; + +pub const MAX_UPPERS: usize = 512; + +pub const MAX_FOLLOWERS: usize = 128; + +/// Optimize the aggregation number for a node based on a list of upper nodes. +/// The goal is to reduce the number of upper nodes, so we try to find a +/// aggregation number that is higher than some of the upper nodes. +/// Returns true if the aggregation number was increased. +#[tracing::instrument(level = Level::TRACE, skip(ctx, balance_queue, node_id, uppers))] +pub fn optimize_aggregation_number_for_uppers( + ctx: &C, + balance_queue: &mut BalanceQueue, + node_id: &C::NodeRef, + leaf: bool, + uppers: StackVec, +) -> bool { + let count = uppers.len(); + let mut root_count = 0; + let mut min = u32::MAX; + let mut max = 0; + let mut uppers_uppers = 0; + for upper_id in uppers.into_iter() { + let upper = ctx.node(&upper_id); + let aggregation_number = upper.aggregation_number(); + if aggregation_number == u32::MAX { + root_count += 1; + } else { + let upper_uppers = upper.uppers().len(); + uppers_uppers += upper_uppers; + if aggregation_number < min { + min = aggregation_number; + } + if aggregation_number > max { + max = aggregation_number; + } + } + } + if min == u32::MAX { + min = LEAF_NUMBER - 1; + } + if max < LEAF_NUMBER { + max = LEAF_NUMBER - 1; + } + let aggregation_number = (min + max) / 2 + 1; + if leaf { + increase_aggregation_number_internal( + ctx, + balance_queue, + ctx.node(node_id), + node_id, + aggregation_number, + aggregation_number, + IncreaseReason::OptimizeForUppers, + ); + return true; + } else { + let normal_count = count - root_count; + if normal_count > 0 { + let avg_uppers_uppers = uppers_uppers / normal_count; + if count > avg_uppers_uppers && root_count * 2 < count { + increase_aggregation_number_internal( + ctx, + balance_queue, + ctx.node(node_id), + node_id, + aggregation_number, + aggregation_number, + IncreaseReason::OptimizeForUppers, + ); + return true; + } + } + } + false +} + +/// Optimize the aggregation number for a node based on a list of followers. +/// The goal is to reduce the number of followers, so we try to find a +/// aggregation number that is higher than some of the followers. +/// Returns true if the aggregation number was increased. +#[tracing::instrument(level = Level::TRACE, skip(ctx, balance_queue, node_id, followers))] +pub fn optimize_aggregation_number_for_followers( + ctx: &C, + balance_queue: &mut BalanceQueue, + node_id: &C::NodeRef, + followers: StackVec, + force: bool, +) -> bool { + let count = followers.len(); + let mut root_count = 0; + let mut min = u32::MAX; + let mut max = 0; + let mut followers_followers = 0; + for follower_id in followers.into_iter() { + let follower = ctx.node(&follower_id); + let aggregation_number = follower.aggregation_number(); + if aggregation_number == u32::MAX { + root_count += 1; + } else { + let follower_followers = follower.followers().map_or(0, |f| f.len()); + followers_followers += follower_followers; + if aggregation_number < min { + min = aggregation_number; + } + if aggregation_number > max { + max = aggregation_number; + } + } + } + if min == u32::MAX { + min = LEAF_NUMBER - 1; + } + if min < LEAF_NUMBER { + min = LEAF_NUMBER - 1; + } + if max < min { + max = min; + } + let normal_count = count - root_count; + if normal_count > 0 { + let avg_followers_followers = followers_followers / normal_count; + let makes_sense = count > avg_followers_followers || force; + if makes_sense && root_count * 2 < count { + let aggregation_number = (min + max) / 2 + 1; + increase_aggregation_number_internal( + ctx, + balance_queue, + ctx.node(node_id), + node_id, + aggregation_number, + aggregation_number, + IncreaseReason::OptimizeForFollowers, + ); + return true; + } + } + false +} diff --git a/crates/turbo-tasks-memory/src/aggregation/root_query.rs b/crates/turbo-tasks-memory/src/aggregation/root_query.rs new file mode 100644 index 0000000000000..74cacffb6961a --- /dev/null +++ b/crates/turbo-tasks-memory/src/aggregation/root_query.rs @@ -0,0 +1,51 @@ +use std::ops::ControlFlow; + +use auto_hash_map::AutoSet; + +use super::{AggregationContext, AggregationNode, StackVec}; + +/// A query about aggregation data in a root node. +pub trait RootQuery { + type Data; + type Result; + + /// Processes the aggregated data of a root node. Can decide to stop the + /// query. + fn query(&mut self, data: &Self::Data) -> ControlFlow<()>; + /// Returns the result of the query. + fn result(self) -> Self::Result; +} + +/// Queries the root node of an aggregation tree. +pub fn query_root_info>( + ctx: &C, + mut query: Q, + node_id: C::NodeRef, +) -> Q::Result { + let mut queue = StackVec::new(); + queue.push(node_id); + let mut visited = AutoSet::new(); + while let Some(node_id) = queue.pop() { + let node = ctx.node(&node_id); + match &*node { + AggregationNode::Leaf { uppers, .. } => { + for upper_id in uppers.iter() { + if visited.insert(upper_id.clone()) { + queue.push(upper_id.clone()); + } + } + } + AggregationNode::Aggegating(aggegrating) => { + if let ControlFlow::Break(_) = query.query(&aggegrating.data) { + return query.result(); + } + for upper_id in aggegrating.uppers.iter() { + if visited.insert(upper_id.clone()) { + queue.push(upper_id.clone()); + } + } + } + } + } + query.result() +} diff --git a/crates/turbo-tasks-memory/src/aggregation/tests.rs b/crates/turbo-tasks-memory/src/aggregation/tests.rs new file mode 100644 index 0000000000000..12af07a9e7453 --- /dev/null +++ b/crates/turbo-tasks-memory/src/aggregation/tests.rs @@ -0,0 +1,1072 @@ +use std::{ + collections::HashSet, + fmt::Debug, + hash::Hash, + iter::once, + ops::{ControlFlow, Deref, DerefMut}, + sync::{ + atomic::{AtomicU32, Ordering}, + Arc, + }, + time::Instant, +}; + +use indexmap::IndexSet; +use nohash_hasher::IsEnabled; +use parking_lot::{Mutex, MutexGuard}; +use rand::{rngs::SmallRng, Rng, SeedableRng}; +use ref_cast::RefCast; +use rstest::*; + +use self::aggregation_data::prepare_aggregation_data; +use super::{ + aggregation_data, handle_new_edge, lost_edge::handle_lost_edges, AggregationContext, + AggregationNode, AggregationNodeGuard, RootQuery, +}; +use crate::aggregation::{query_root_info, PreparedOperation, StackVec}; + +fn find_root(mut node: NodeRef) -> NodeRef { + loop { + let lock = node.0.inner.lock(); + let uppers = lock.aggregation_node.uppers(); + if uppers.is_empty() { + drop(lock); + return node; + } + let upper = uppers.iter().next().unwrap().clone(); + drop(lock); + node = upper; + } +} + +fn check_invariants<'a>( + ctx: &NodeAggregationContext<'a>, + node_ids: impl IntoIterator, +) { + let mut queue = node_ids.into_iter().collect::>(); + // print(ctx, &queue[0], true); + let mut visited = HashSet::new(); + while let Some(node_id) = queue.pop() { + assert_eq!(node_id.0.atomic.load(Ordering::SeqCst), 0); + let node = ctx.node(&node_id); + for child_id in node.children() { + if visited.insert(child_id.clone()) { + queue.push(child_id.clone()); + } + } + + let aggregation_number = node.aggregation_number(); + let node_value = node.guard.value; + let uppers = match &*node { + AggregationNode::Leaf { uppers, .. } => { + let uppers = uppers.iter().cloned().collect::>(); + drop(node); + uppers + } + AggregationNode::Aggegating(aggegrating) => { + let uppers = aggegrating.uppers.iter().cloned().collect::>(); + let followers = aggegrating + .followers + .iter() + .cloned() + .collect::>(); + drop(node); + for follower_id in followers { + let follower_aggregation_number; + let follower_uppers; + let follower_value; + { + let follower = ctx.node(&follower_id); + + follower_aggregation_number = follower.aggregation_number(); + follower_uppers = + follower.uppers().iter().cloned().collect::>(); + follower_value = follower.guard.value; + } + + // A follower should have a bigger aggregation number + let condition = follower_aggregation_number > aggregation_number + || aggregation_number == u32::MAX; + if !condition { + let msg = format!( + "follower #{} {} -> #{} {}", + node_value, + aggregation_number, + follower_value, + follower_aggregation_number + ); + print(ctx, &find_root(node_id.clone()), true); + panic!("{msg}"); + } + + // All followers should also be connected to all uppers + let missing_uppers = uppers.iter().filter(|&upper_id| { + if follower_uppers + .iter() + .any(|follower_upper_id| follower_upper_id == upper_id) + { + return false; + } + let upper = ctx.node(upper_id); + if let Some(followers) = upper.followers() { + !followers + .iter() + .any(|follower_upper_id| follower_upper_id == &follower_id) + } else { + false + } + }); + for missing_upper in missing_uppers { + let upper_value = { + let upper = ctx.node(missing_upper); + upper.guard.value + }; + let msg = format!( + "follower #{} -> #{} is not connected to upper #{}", + node_value, follower_value, upper_value, + ); + print(ctx, &find_root(node_id.clone()), true); + panic!("{msg}"); + } + + // And visit them too + if visited.insert(follower_id.clone()) { + queue.push(follower_id); + } + } + uppers + } + }; + for upper_id in uppers { + { + let upper = ctx.node(&upper_id); + let upper_aggregation_number = upper.aggregation_number(); + let condition = + upper_aggregation_number > aggregation_number || aggregation_number == u32::MAX; + if !condition { + let msg = format!( + "upper #{} {} -> #{} {}", + node_value, aggregation_number, upper.guard.value, upper_aggregation_number + ); + drop(upper); + print(ctx, &find_root(upper_id.clone()), true); + panic!("{msg}"); + } + } + if visited.insert(upper_id.clone()) { + queue.push(upper_id); + } + } + } +} + +fn print_graph( + ctx: &C, + entries: impl IntoIterator, + show_internal: bool, + name_fn: impl Fn(&C::NodeRef) -> String, +) { + let mut queue = entries.into_iter().collect::>(); + let mut visited = queue.iter().cloned().collect::>(); + while let Some(node_id) = queue.pop() { + let name = name_fn(&node_id); + let node = ctx.node(&node_id); + let n = node.aggregation_number(); + let n = if n == u32::MAX { + "♾".to_string() + } else { + n.to_string() + }; + let color = if matches!(*node, AggregationNode::Leaf { .. }) { + "gray" + } else { + "#99ff99" + }; + let children = node.children().collect::>(); + let uppers = node.uppers().iter().cloned().collect::>(); + let followers = match &*node { + AggregationNode::Aggegating(aggegrating) => aggegrating + .followers + .iter() + .cloned() + .collect::>(), + AggregationNode::Leaf { .. } => StackVec::new(), + }; + drop(node); + + if show_internal { + println!( + "\"{}\" [label=\"{}\\n{}\", style=filled, fillcolor=\"{}\"];", + name, name, n, color + ); + } else { + println!( + "\"{}\" [label=\"{}\\n{}\\n{}U {}F\", style=filled, fillcolor=\"{}\"];", + name, + name, + n, + uppers.len(), + followers.len(), + color, + ); + } + + for child_id in children { + let child_name = name_fn(&child_id); + println!("\"{}\" -> \"{}\";", name, child_name); + if visited.insert(child_id.clone()) { + queue.push(child_id); + } + } + if show_internal { + for upper_id in uppers { + let upper_name = name_fn(&upper_id); + println!( + "\"{}\" -> \"{}\" [style=dashed, color=green];", + name, upper_name + ); + if visited.insert(upper_id.clone()) { + queue.push(upper_id); + } + } + for follower_id in followers { + let follower_name = name_fn(&follower_id); + println!( + "\"{}\" -> \"{}\" [style=dashed, color=red];", + name, follower_name + ); + if visited.insert(follower_id.clone()) { + queue.push(follower_id); + } + } + } + } +} + +struct Node { + atomic: AtomicU32, + inner: Mutex, +} + +impl Node { + fn new(value: u32) -> Arc { + Arc::new(Node { + atomic: AtomicU32::new(0), + inner: Mutex::new(NodeInner { + children: Vec::new(), + aggregation_node: AggregationNode::new(), + value, + }), + }) + } + + fn new_with_children( + aggregation_context: &NodeAggregationContext, + value: u32, + children: Vec>, + ) -> Arc { + let node = Self::new(value); + for child in children { + node.add_child(aggregation_context, child); + } + node + } + + fn add_child(self: &Arc, aggregation_context: &NodeAggregationContext, child: Arc) { + self.add_child_unchecked(aggregation_context, child); + check_invariants(aggregation_context, once(find_root(NodeRef(self.clone())))); + } + + fn add_child_unchecked( + self: &Arc, + aggregation_context: &NodeAggregationContext, + child: Arc, + ) { + let mut guard = self.inner.lock(); + guard.children.push(child.clone()); + let number_of_children = guard.children.len(); + let mut guard = unsafe { NodeGuard::new(guard, self.clone()) }; + let prepared = handle_new_edge( + aggregation_context, + &mut guard, + &NodeRef(self.clone()), + &NodeRef(child), + number_of_children, + ); + drop(guard); + prepared.apply(aggregation_context); + } + + fn prepare_add_child<'c>( + self: &Arc, + aggregation_context: &'c NodeAggregationContext<'c>, + child: Arc, + ) -> impl PreparedOperation> { + let mut guard = self.inner.lock(); + guard.children.push(child.clone()); + let number_of_children = guard.children.len(); + let mut guard = unsafe { NodeGuard::new(guard, self.clone()) }; + handle_new_edge( + aggregation_context, + &mut guard, + &NodeRef(self.clone()), + &NodeRef(child), + number_of_children, + ) + } + + fn prepare_aggregation_number<'c>( + self: &Arc, + aggregation_context: &'c NodeAggregationContext<'c>, + aggregation_number: u32, + ) -> impl PreparedOperation> { + let mut guard = self.inner.lock(); + guard.aggregation_node.increase_aggregation_number( + aggregation_context, + &NodeRef(self.clone()), + aggregation_number, + ) + } + + fn remove_child( + self: &Arc, + aggregation_context: &NodeAggregationContext, + child: &Arc, + ) { + self.remove_child_unchecked(aggregation_context, child); + check_invariants(aggregation_context, once(NodeRef(self.clone()))); + } + + fn remove_child_unchecked( + self: &Arc, + aggregation_context: &NodeAggregationContext, + child: &Arc, + ) { + let mut guard = self.inner.lock(); + if let Some(idx) = guard + .children + .iter() + .position(|item| Arc::ptr_eq(item, child)) + { + guard.children.swap_remove(idx); + handle_lost_edges( + aggregation_context, + unsafe { NodeGuard::new(guard, self.clone()) }, + &NodeRef(self.clone()), + [NodeRef(child.clone())], + ); + } + } + + fn incr(self: &Arc, aggregation_context: &NodeAggregationContext) { + let mut guard = self.inner.lock(); + guard.value += 10000; + let prepared = guard + .aggregation_node + .apply_change(aggregation_context, Change { value: 10000 }); + drop(guard); + prepared.apply(aggregation_context); + check_invariants(aggregation_context, once(NodeRef(self.clone()))); + } +} + +#[derive(Copy, Clone)] +struct Change { + value: i32, +} + +impl Change { + fn is_empty(&self) -> bool { + self.value == 0 + } +} + +struct NodeInner { + children: Vec>, + aggregation_node: AggregationNode, + value: u32, +} + +struct NodeAggregationContext<'a> { + additions: AtomicU32, + #[allow(dead_code)] + something_with_lifetime: &'a u32, + add_value: bool, +} + +#[derive(Clone, RefCast)] +#[repr(transparent)] +struct NodeRef(Arc); + +impl Debug for NodeRef { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "NodeRef({})", self.0.inner.lock().value) + } +} + +impl Hash for NodeRef { + fn hash(&self, state: &mut H) { + Arc::as_ptr(&self.0).hash(state); + } +} + +impl IsEnabled for NodeRef {} + +impl PartialEq for NodeRef { + fn eq(&self, other: &Self) -> bool { + Arc::ptr_eq(&self.0, &other.0) + } +} + +impl Eq for NodeRef {} + +struct NodeGuard { + guard: MutexGuard<'static, NodeInner>, + // This field is important to keep the node alive + #[allow(dead_code)] + node: Arc, +} + +impl NodeGuard { + unsafe fn new(guard: MutexGuard<'_, NodeInner>, node: Arc) -> Self { + NodeGuard { + guard: unsafe { std::mem::transmute(guard) }, + node, + } + } +} + +impl Deref for NodeGuard { + type Target = AggregationNode; + + fn deref(&self) -> &Self::Target { + &self.guard.aggregation_node + } +} + +impl DerefMut for NodeGuard { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.guard.aggregation_node + } +} + +impl AggregationNodeGuard for NodeGuard { + type Data = Aggregated; + type NodeRef = NodeRef; + type DataChange = Change; + type ChildrenIter<'a> = impl Iterator + 'a; + + fn children(&self) -> Self::ChildrenIter<'_> { + self.guard + .children + .iter() + .map(|child| NodeRef(child.clone())) + } + + fn get_remove_change(&self) -> Option { + let change = Change { + value: -(self.guard.value as i32), + }; + if change.is_empty() { + None + } else { + Some(change) + } + } + + fn get_add_change(&self) -> Option { + let change = Change { + value: self.guard.value as i32, + }; + if change.is_empty() { + None + } else { + Some(change) + } + } + + fn get_initial_data(&self) -> Self::Data { + Aggregated { + value: self.guard.value as i32, + active: false, + } + } +} + +impl<'a> AggregationContext for NodeAggregationContext<'a> { + type Guard<'l> = NodeGuard where Self: 'l; + type Data = Aggregated; + type NodeRef = NodeRef; + type DataChange = Change; + + fn node<'b>(&'b self, reference: &Self::NodeRef) -> Self::Guard<'b> { + let r = reference.0.clone(); + let guard = reference.0.inner.lock(); + unsafe { NodeGuard::new(guard, r) } + } + + fn atomic_in_progress_counter<'l>(&self, id: &'l Self::NodeRef) -> &'l AtomicU32 + where + Self: 'l, + { + &id.0.atomic + } + + fn apply_change(&self, data: &mut Aggregated, change: &Change) -> Option { + if data.value != 0 { + self.additions.fetch_add(1, Ordering::SeqCst); + } + if self.add_value { + data.value += change.value; + Some(*change) + } else { + None + } + } + + fn data_to_add_change(&self, data: &Self::Data) -> Option { + let change = Change { value: data.value }; + if change.is_empty() { + None + } else { + Some(change) + } + } + + fn data_to_remove_change(&self, data: &Self::Data) -> Option { + let change = Change { value: -data.value }; + if change.is_empty() { + None + } else { + Some(change) + } + } +} + +#[derive(Default)] +struct ActiveQuery { + active: bool, +} + +impl RootQuery for ActiveQuery { + type Data = Aggregated; + type Result = bool; + + fn query(&mut self, data: &Self::Data) -> ControlFlow<()> { + if data.active { + self.active = true; + ControlFlow::Break(()) + } else { + ControlFlow::Continue(()) + } + } + + fn result(self) -> Self::Result { + self.active + } +} + +#[derive(Default)] +struct Aggregated { + value: i32, + active: bool, +} + +#[test] +fn chain() { + let something_with_lifetime = 0; + let ctx = NodeAggregationContext { + additions: AtomicU32::new(0), + something_with_lifetime: &something_with_lifetime, + add_value: true, + }; + let root = Node::new(1); + let mut current = root.clone(); + for i in 2..=100 { + let node = Node::new(i); + current.add_child(&ctx, node.clone()); + current = node; + } + let leaf = Node::new(10000); + current.add_child(&ctx, leaf.clone()); + let current = NodeRef(root); + + { + let root_info = query_root_info(&ctx, ActiveQuery::default(), NodeRef(leaf.clone())); + assert!(!root_info); + } + + { + let aggregated = aggregation_data(&ctx, ¤t); + assert_eq!(aggregated.value, 15050); + } + assert_eq!(ctx.additions.load(Ordering::SeqCst), 122); + ctx.additions.store(0, Ordering::SeqCst); + check_invariants(&ctx, once(current.clone())); + + { + let root_info = query_root_info(&ctx, ActiveQuery::default(), NodeRef(leaf.clone())); + assert!(!root_info); + } + check_invariants(&ctx, once(current.clone())); + + leaf.incr(&ctx); + // The change need to propagate through 2 aggregated nodes + assert_eq!(ctx.additions.load(Ordering::SeqCst), 2); + ctx.additions.store(0, Ordering::SeqCst); + + { + let mut aggregated = aggregation_data(&ctx, ¤t); + assert_eq!(aggregated.value, 25050); + aggregated.active = true; + } + assert_eq!(ctx.additions.load(Ordering::SeqCst), 0); + ctx.additions.store(0, Ordering::SeqCst); + + { + let root_info = query_root_info(&ctx, ActiveQuery::default(), NodeRef(leaf.clone())); + assert!(root_info); + } + + let i = 101; + let current = Node::new_with_children(&ctx, i, vec![current.0]); + let current = NodeRef(current); + + { + let aggregated = aggregation_data(&ctx, ¤t); + assert_eq!(aggregated.value, 25151); + } + // This should be way less the 100 to prove that we are reusing trees + assert_eq!(ctx.additions.load(Ordering::SeqCst), 1); + ctx.additions.store(0, Ordering::SeqCst); + + leaf.incr(&ctx); + // This should be less the 20 to prove that we are reusing trees + assert_eq!(ctx.additions.load(Ordering::SeqCst), 3); + ctx.additions.store(0, Ordering::SeqCst); + + { + let root_info = query_root_info(&ctx, ActiveQuery::default(), NodeRef(leaf.clone())); + assert!(root_info); + } + + print(&ctx, ¤t, true); + check_invariants(&ctx, once(current.clone())); +} + +#[test] +fn chain_double_connected() { + let something_with_lifetime = 0; + let ctx = NodeAggregationContext { + additions: AtomicU32::new(0), + something_with_lifetime: &something_with_lifetime, + add_value: true, + }; + let root = Node::new(1); + let mut nodes = vec![root.clone()]; + let mut current = root.clone(); + let mut current2 = Node::new(2); + current.add_child(&ctx, current2.clone()); + nodes.push(current2.clone()); + for i in 3..=100 { + let node = Node::new(i); + nodes.push(node.clone()); + current.add_child(&ctx, node.clone()); + current2.add_child(&ctx, node.clone()); + current = current2; + current2 = node; + } + let current = NodeRef(root); + + { + let aggregated = aggregation_data(&ctx, ¤t); + assert_eq!(aggregated.value, 13188); + } + check_invariants(&ctx, once(current.clone())); + assert_eq!(ctx.additions.load(Ordering::SeqCst), 285); + ctx.additions.store(0, Ordering::SeqCst); + + print(&ctx, ¤t, true); + + for i in 2..nodes.len() { + nodes[i - 2].remove_child(&ctx, &nodes[i]); + nodes[i - 1].remove_child(&ctx, &nodes[i]); + } + nodes[0].remove_child(&ctx, &nodes[1]); + + { + let aggregated = aggregation_data(&ctx, ¤t); + assert_eq!(aggregated.value, 1); + } +} + +const RECT_SIZE: usize = 30; +const RECT_MULT: usize = 100; + +#[test] +fn rectangle_tree() { + let something_with_lifetime = 0; + let ctx = NodeAggregationContext { + additions: AtomicU32::new(0), + something_with_lifetime: &something_with_lifetime, + add_value: false, + }; + let mut nodes: Vec>> = Vec::new(); + let mut extra_nodes = Vec::new(); + for y in 0..RECT_SIZE { + let mut line: Vec> = Vec::new(); + for x in 0..RECT_SIZE { + let mut parents = Vec::new(); + if x > 0 { + parents.push(line[x - 1].clone()); + } + if y > 0 { + parents.push(nodes[y - 1][x].clone()); + } + let value = (x + y * RECT_MULT) as u32; + let node = Node::new(value); + if x == 0 || y == 0 { + let extra_node = Node::new(value + 100000); + prepare_aggregation_data(&ctx, &NodeRef(extra_node.clone())); + extra_node.add_child(&ctx, node.clone()); + extra_nodes.push(extra_node); + prepare_aggregation_data(&ctx, &NodeRef(node.clone())); + } + for parent in parents { + parent.add_child_unchecked(&ctx, node.clone()); + } + if x == 0 || y == 0 { + prepare_aggregation_data(&ctx, &NodeRef(node.clone())); + } + line.push(node); + } + nodes.push(line); + } + + check_invariants(&ctx, extra_nodes.iter().cloned().map(NodeRef)); + + let root = NodeRef(extra_nodes[0].clone()); + print(&ctx, &root, false); +} + +#[rstest] +#[case::many_roots_initial(100000, 0, 2, 1)] +#[case::many_roots_later(1, 100000, 2, 1)] +#[case::many_roots_later2(0, 100000, 2, 1)] +#[case::many_roots(50000, 50000, 2, 1)] +#[case::many_children(2, 0, 100000, 1)] +#[case::many_roots_and_children(5000, 5000, 10000, 1)] +#[case::many_roots_and_subgraph(5000, 5000, 100, 2)] +#[case::large_subgraph_a(9, 1, 10, 5)] +#[case::large_subgraph_b(5, 5, 10, 5)] +#[case::large_subgraph_c(1, 9, 10, 5)] +#[case::large_subgraph_d(6, 0, 10, 5)] +#[case::large_subgraph_e(0, 10, 10, 5)] +#[case::many_roots_large_subgraph(5000, 5000, 10, 5)] +fn performance( + #[case] initial_root_count: u32, + #[case] additional_root_count: u32, + #[case] children_count: u32, + #[case] children_layers_count: u32, +) { + fn print_aggregation_numbers(node: Arc) { + print!("Aggregation numbers "); + let mut current = node.clone(); + loop { + let guard = current.inner.lock(); + let n = guard.aggregation_node.aggregation_number(); + let f = guard.aggregation_node.followers().map_or(0, |f| f.len()); + let u = guard.aggregation_node.uppers().len(); + print!(" -> {} [{}U {}F]", n, u, f); + if guard.children.is_empty() { + break; + } + let child = guard.children[guard.children.len() / 2].clone(); + drop(guard); + current = child; + } + println!(); + } + + let something_with_lifetime = 0; + let ctx = NodeAggregationContext { + additions: AtomicU32::new(0), + something_with_lifetime: &something_with_lifetime, + add_value: false, + }; + let mut roots: Vec> = Vec::new(); + let inner_node = Node::new(0); + // Setup + for i in 0..initial_root_count { + let node = Node::new(2 + i); + roots.push(node.clone()); + aggregation_data(&ctx, &NodeRef(node.clone())).active = true; + node.add_child_unchecked(&ctx, inner_node.clone()); + } + let start = Instant::now(); + let mut children = vec![inner_node.clone()]; + for j in 0..children_layers_count { + let mut new_children = Vec::new(); + for child in children { + for i in 0..children_count { + let node = Node::new(1000000 * (j + 1) + i); + new_children.push(node.clone()); + child.add_child_unchecked(&ctx, node.clone()); + } + } + children = new_children; + } + println!("Setup children: {:?}", start.elapsed()); + + print_aggregation_numbers(inner_node.clone()); + + let start = Instant::now(); + for i in 0..additional_root_count { + let node = Node::new(2 + i); + roots.push(node.clone()); + aggregation_data(&ctx, &NodeRef(node.clone())).active = true; + node.add_child_unchecked(&ctx, inner_node.clone()); + } + println!("Setup additional roots: {:?}", start.elapsed()); + + print_aggregation_numbers(inner_node.clone()); + + // Add another root + let start = Instant::now(); + { + let node = Node::new(1); + roots.push(node.clone()); + aggregation_data(&ctx, &NodeRef(node.clone())).active = true; + node.add_child_unchecked(&ctx, inner_node.clone()); + } + let root_duration = start.elapsed(); + println!("Root: {:?}", root_duration); + + // Add another child + let start = Instant::now(); + { + let node = Node::new(999999); + inner_node.add_child_unchecked(&ctx, node.clone()); + } + let child_duration = start.elapsed(); + println!("Child: {:?}", child_duration); + + print_aggregation_numbers(inner_node.clone()); + + assert!(root_duration.as_micros() < 10000); + assert!(child_duration.as_micros() < 10000); + + // check_invariants(&ctx, roots.iter().cloned().map(NodeRef)); +} + +#[test] +fn many_children() { + let something_with_lifetime = 0; + let ctx = NodeAggregationContext { + additions: AtomicU32::new(0), + something_with_lifetime: &something_with_lifetime, + add_value: false, + }; + let mut roots: Vec> = Vec::new(); + let mut children: Vec> = Vec::new(); + const CHILDREN: u32 = 100000; + const ROOTS: u32 = 3; + let inner_node = Node::new(0); + let start = Instant::now(); + for i in 0..ROOTS { + let node = Node::new(10000 + i); + roots.push(node.clone()); + aggregation_data(&ctx, &NodeRef(node.clone())).active = true; + node.add_child_unchecked(&ctx, inner_node.clone()); + } + println!("Roots: {:?}", start.elapsed()); + let start = Instant::now(); + for i in 0..CHILDREN { + let node = Node::new(20000 + i); + children.push(node.clone()); + inner_node.add_child_unchecked(&ctx, node.clone()); + } + println!("Children: {:?}", start.elapsed()); + let start = Instant::now(); + for i in 0..CHILDREN { + let node = Node::new(40000 + i); + children.push(node.clone()); + inner_node.add_child_unchecked(&ctx, node.clone()); + } + let children_duration = start.elapsed(); + println!("Children: {:?}", children_duration); + for j in 0.. { + let start = Instant::now(); + for i in 0..CHILDREN { + let node = Node::new(50000 + j * 10000 + i); + children.push(node.clone()); + inner_node.add_child_unchecked(&ctx, node.clone()); + } + let dur = start.elapsed(); + println!("Children: {:?}", dur); + let is_slow = dur > children_duration * 2; + if j > 10 && !is_slow { + break; + } + if j > 20 { + panic!("Adding children has become slower over time"); + } + } + + let start = Instant::now(); + for i in 0..ROOTS { + let node = Node::new(30000 + i); + roots.push(node.clone()); + aggregation_data(&ctx, &NodeRef(node.clone())).active = true; + node.add_child_unchecked(&ctx, inner_node.clone()); + } + println!("Roots: {:?}", start.elapsed()); + + check_invariants(&ctx, roots.iter().cloned().map(NodeRef)); + + // let root = NodeRef(roots[0].clone()); + // print(&ctx, &root, false); +} + +#[test] +fn concurrent_modification() { + let something_with_lifetime = 0; + let ctx = NodeAggregationContext { + additions: AtomicU32::new(0), + something_with_lifetime: &something_with_lifetime, + add_value: true, + }; + let root1 = Node::new(1); + let root2 = Node::new(2); + let helper = Node::new(3); + let inner_node = Node::new(10); + let outer_node1 = Node::new(11); + let outer_node2 = Node::new(12); + let outer_node3 = Node::new(13); + let outer_node4 = Node::new(14); + inner_node.add_child(&ctx, outer_node1.clone()); + inner_node.add_child(&ctx, outer_node2.clone()); + root2.add_child(&ctx, helper.clone()); + outer_node1.prepare_aggregation_number(&ctx, 7).apply(&ctx); + outer_node3.prepare_aggregation_number(&ctx, 7).apply(&ctx); + root1.prepare_aggregation_number(&ctx, 8).apply(&ctx); + root2.prepare_aggregation_number(&ctx, 4).apply(&ctx); + helper.prepare_aggregation_number(&ctx, 3).apply(&ctx); + + let add_job1 = root1.prepare_add_child(&ctx, inner_node.clone()); + let add_job2 = inner_node.prepare_add_child(&ctx, outer_node3.clone()); + let add_job3 = inner_node.prepare_add_child(&ctx, outer_node4.clone()); + let add_job4 = helper.prepare_add_child(&ctx, inner_node.clone()); + + add_job4.apply(&ctx); + print_all(&ctx, [root1.clone(), root2.clone()].map(NodeRef), true); + add_job3.apply(&ctx); + print_all(&ctx, [root1.clone(), root2.clone()].map(NodeRef), true); + add_job2.apply(&ctx); + print_all(&ctx, [root1.clone(), root2.clone()].map(NodeRef), true); + add_job1.apply(&ctx); + + print_all(&ctx, [root1.clone(), root2.clone()].map(NodeRef), true); + + check_invariants(&ctx, [root1, root2].map(NodeRef)); +} + +#[test] +fn fuzzy_new() { + for size in [10, 50, 100, 200, 1000] { + for _ in 0..100 { + let seed = rand::random(); + println!("Seed {} Size {}", seed, size); + fuzzy(seed, size); + } + } +} + +#[rstest] +#[case::a(4059591975, 10)] +#[case::b(603692396, 100)] +#[case::c(3317876847, 10)] +#[case::d(4012518846, 50)] +fn fuzzy(#[case] seed: u32, #[case] count: u32) { + let something_with_lifetime = 0; + let ctx = NodeAggregationContext { + additions: AtomicU32::new(0), + something_with_lifetime: &something_with_lifetime, + add_value: true, + }; + + let mut seed_buffer = [0; 32]; + seed_buffer[0..4].copy_from_slice(&seed.to_be_bytes()); + let mut r = SmallRng::from_seed(seed_buffer); + let mut nodes = Vec::new(); + for i in 0..count { + nodes.push(Node::new(i)); + } + prepare_aggregation_data(&ctx, &NodeRef(nodes[0].clone())); + + let mut edges = IndexSet::new(); + + for _ in 0..1000 { + match r.gen_range(0..=2) { + 0 | 1 => { + // if x == 47 { + // print_all(&ctx, nodes.iter().cloned().map(NodeRef), true); + // } + // add edge + let parent = r.gen_range(0..nodes.len() - 1); + let child = r.gen_range(parent + 1..nodes.len()); + // println!("add edge {} -> {}", parent, child); + if edges.insert((parent, child)) { + nodes[parent].add_child(&ctx, nodes[child].clone()); + } + } + 2 => { + // remove edge + if edges.is_empty() { + continue; + } + let i = r.gen_range(0..edges.len()); + let (parent, child) = edges.swap_remove_index(i).unwrap(); + // println!("remove edge {} -> {}", parent, child); + nodes[parent].remove_child(&ctx, &nodes[child]); + } + _ => unreachable!(), + } + } + + for (parent, child) in edges { + nodes[parent].remove_child(&ctx, &nodes[child]); + } + + assert_eq!(aggregation_data(&ctx, &NodeRef(nodes[0].clone())).value, 0); + + check_invariants(&ctx, nodes.iter().cloned().map(NodeRef)); + + for node in nodes { + let lock = node.inner.lock(); + if let AggregationNode::Aggegating(a) = &lock.aggregation_node { + assert_eq!(a.data.value, lock.value as i32); + } + } +} + +fn print(aggregation_context: &NodeAggregationContext<'_>, root: &NodeRef, show_internal: bool) { + print_all(aggregation_context, once(root.clone()), show_internal); +} + +fn print_all( + aggregation_context: &NodeAggregationContext<'_>, + nodes: impl IntoIterator, + show_internal: bool, +) { + println!("digraph {{"); + print_graph(aggregation_context, nodes, show_internal, |item| { + let lock = item.0.inner.lock(); + if let AggregationNode::Aggegating(a) = &lock.aggregation_node { + format!("#{} [{}]", lock.value, a.data.value) + } else { + format!("#{}", lock.value) + } + }); + println!("\n}}"); +} diff --git a/crates/turbo-tasks-memory/src/aggregation/uppers.rs b/crates/turbo-tasks-memory/src/aggregation/uppers.rs new file mode 100644 index 0000000000000..e131962cd280b --- /dev/null +++ b/crates/turbo-tasks-memory/src/aggregation/uppers.rs @@ -0,0 +1,256 @@ +use super::{ + balance_queue::BalanceQueue, + in_progress::start_in_progress_count, + optimize::{optimize_aggregation_number_for_uppers, MAX_UPPERS}, + AggegatingNode, AggregationContext, AggregationNode, AggregationNodeGuard, + PreparedInternalOperation, PreparedOperation, StackVec, +}; +use crate::count_hash_set::RemovePositiveCountResult; + +/// Adds an upper node to a node. Returns the number of affected nodes by this +/// operation. This will also propagate the followers to the new upper node. +pub fn add_upper( + ctx: &C, + balance_queue: &mut BalanceQueue, + node: C::Guard<'_>, + node_id: &C::NodeRef, + upper_id: &C::NodeRef, + already_optimizing_for_upper: bool, +) -> usize { + add_upper_count( + ctx, + balance_queue, + node, + node_id, + upper_id, + 1, + already_optimizing_for_upper, + ) + .affected_nodes +} + +pub struct AddUpperCountResult { + pub new_count: isize, + pub affected_nodes: usize, +} + +/// Adds an upper node to a node with a given count. Returns the new count of +/// the upper node and the number of affected nodes by this operation. This will +/// also propagate the followers to the new upper node. +pub fn add_upper_count( + ctx: &C, + balance_queue: &mut BalanceQueue, + mut node: C::Guard<'_>, + node_id: &C::NodeRef, + upper_id: &C::NodeRef, + count: usize, + already_optimizing_for_upper: bool, +) -> AddUpperCountResult { + // TODO add_clonable_count could return the current count for better performance + let (added, count) = match &mut *node { + AggregationNode::Leaf { uppers, .. } => { + if uppers.add_clonable_count(upper_id, count) { + let count = uppers.get_count(upper_id); + (true, count) + } else { + (false, uppers.get_count(upper_id)) + } + } + AggregationNode::Aggegating(aggegating) => { + let AggegatingNode { ref mut uppers, .. } = **aggegating; + if uppers.add_clonable_count(upper_id, count) { + let count = uppers.get_count(upper_id); + (true, count) + } else { + (false, uppers.get_count(upper_id)) + } + } + }; + let mut affected_nodes = 0; + if added { + affected_nodes = on_added( + ctx, + balance_queue, + node, + node_id, + upper_id, + already_optimizing_for_upper, + ); + } else { + drop(node); + } + AddUpperCountResult { + new_count: count, + affected_nodes, + } +} + +/// Called when an upper node was added to a node. This will propagate the +/// followers to the new upper node. +pub fn on_added( + ctx: &C, + balance_queue: &mut BalanceQueue, + mut node: C::Guard<'_>, + node_id: &C::NodeRef, + upper_id: &C::NodeRef, + already_optimizing_for_upper: bool, +) -> usize { + let uppers = node.uppers(); + let uppers_len = uppers.len(); + let optimize = (!already_optimizing_for_upper + && uppers_len > MAX_UPPERS + && (uppers_len - MAX_UPPERS).count_ones() == 1) + .then(|| (true, uppers.iter().cloned().collect::>())); + let (add_change, followers) = match &mut *node { + AggregationNode::Leaf { .. } => { + let add_change = node.get_add_change(); + let children = node.children().collect::>(); + start_in_progress_count(ctx, upper_id, children.len() as u32); + drop(node); + (add_change, children) + } + AggregationNode::Aggegating(aggegating) => { + let AggegatingNode { ref followers, .. } = **aggegating; + let add_change = ctx.data_to_add_change(&aggegating.data); + let followers = followers.iter().cloned().collect::>(); + start_in_progress_count(ctx, upper_id, followers.len() as u32); + drop(node); + + (add_change, followers) + } + }; + + let mut optimizing = false; + + // This heuristic ensures that we don’t have too many upper edges, which would + // degrade update performance + if let Some((leaf, uppers)) = optimize { + optimizing = + optimize_aggregation_number_for_uppers(ctx, balance_queue, node_id, leaf, uppers); + } + + let mut affected_nodes = 0; + + // Make sure to propagate the change to the upper node + let mut upper = ctx.node(upper_id); + let add_prepared = add_change.and_then(|add_change| upper.apply_change(ctx, add_change)); + affected_nodes += followers.len(); + let prepared = followers + .into_iter() + .filter_map(|child_id| { + upper.notify_new_follower(ctx, balance_queue, upper_id, &child_id, optimizing) + }) + .collect::>(); + drop(upper); + add_prepared.apply(ctx); + for prepared in prepared { + affected_nodes += prepared.apply(ctx, balance_queue); + } + + affected_nodes +} + +/// Removes an upper node from a node with a count. +pub fn remove_upper_count( + ctx: &C, + balance_queue: &mut BalanceQueue, + mut node: C::Guard<'_>, + upper_id: &C::NodeRef, + count: usize, +) { + let removed = match &mut *node { + AggregationNode::Leaf { uppers, .. } => uppers.remove_clonable_count(upper_id, count), + AggregationNode::Aggegating(aggegating) => { + let AggegatingNode { ref mut uppers, .. } = **aggegating; + uppers.remove_clonable_count(upper_id, count) + } + }; + if removed { + on_removed(ctx, balance_queue, node, upper_id); + } +} + +pub struct RemovePositiveUpperCountResult { + pub removed_count: usize, + pub remaining_count: isize, +} + +/// Removes a positive count of an upper node from a node. +/// Returns the removed count and the remaining count of the upper node. +/// This will also propagate the followers to the removed upper node. +pub fn remove_positive_upper_count( + ctx: &C, + balance_queue: &mut BalanceQueue, + mut node: C::Guard<'_>, + upper_id: &C::NodeRef, + count: usize, +) -> RemovePositiveUpperCountResult { + let RemovePositiveCountResult { + removed, + removed_count, + count, + } = match &mut *node { + AggregationNode::Leaf { uppers, .. } => { + uppers.remove_positive_clonable_count(upper_id, count) + } + AggregationNode::Aggegating(aggegating) => { + let AggegatingNode { ref mut uppers, .. } = **aggegating; + uppers.remove_positive_clonable_count(upper_id, count) + } + }; + if removed { + on_removed(ctx, balance_queue, node, upper_id); + } + RemovePositiveUpperCountResult { + removed_count, + remaining_count: count, + } +} + +/// Called when an upper node was removed from a node. This will propagate the +/// followers to the removed upper node. +pub fn on_removed( + ctx: &C, + balance_queue: &mut BalanceQueue, + node: C::Guard<'_>, + upper_id: &C::NodeRef, +) { + match &*node { + AggregationNode::Leaf { .. } => { + let remove_change = node.get_remove_change(); + let children = node.children().collect::>(); + drop(node); + let mut upper = ctx.node(upper_id); + let remove_prepared = + remove_change.and_then(|remove_change| upper.apply_change(ctx, remove_change)); + start_in_progress_count(ctx, upper_id, children.len() as u32); + let prepared = children + .into_iter() + .map(|child_id| upper.notify_lost_follower(ctx, balance_queue, upper_id, &child_id)) + .collect::>(); + drop(upper); + remove_prepared.apply(ctx); + prepared.apply(ctx, balance_queue); + } + AggregationNode::Aggegating(aggegating) => { + let remove_change = ctx.data_to_remove_change(&aggegating.data); + let followers = aggegating + .followers + .iter() + .cloned() + .collect::>(); + drop(node); + let mut upper = ctx.node(upper_id); + let remove_prepared = + remove_change.and_then(|remove_change| upper.apply_change(ctx, remove_change)); + start_in_progress_count(ctx, upper_id, followers.len() as u32); + let prepared = followers + .into_iter() + .map(|child_id| upper.notify_lost_follower(ctx, balance_queue, upper_id, &child_id)) + .collect::>(); + drop(upper); + remove_prepared.apply(ctx); + prepared.apply(ctx, balance_queue); + } + } +} diff --git a/crates/turbo-tasks-memory/src/aggregation_tree/bottom_connection.rs b/crates/turbo-tasks-memory/src/aggregation_tree/bottom_connection.rs deleted file mode 100644 index 2efd9e71cf144..0000000000000 --- a/crates/turbo-tasks-memory/src/aggregation_tree/bottom_connection.rs +++ /dev/null @@ -1,346 +0,0 @@ -use std::{hash::Hash, ops::ControlFlow, sync::Arc}; - -use auto_hash_map::{map::RawEntry, AutoMap}; -use nohash_hasher::{BuildNoHashHasher, IsEnabled}; - -use super::{ - bottom_tree::BottomTree, - inner_refs::{BottomRef, ChildLocation}, - AggregationContext, StackVec, -}; - -struct BottomRefInfo { - count: isize, - distance: u8, -} - -/// A map that stores references to bottom trees which a specific distance. It -/// stores the minimum distance added to the map. -/// -/// This is used to store uppers of leafs or smaller bottom trees with the -/// current distance. The distance is imporant to keep the correct connectivity. -#[derive(Default)] -pub struct DistanceCountMap { - map: AutoMap>, -} - -impl DistanceCountMap { - pub fn new() -> Self { - Self { - map: AutoMap::with_hasher(), - } - } - - pub fn is_unset(&self) -> bool { - self.map.is_empty() - } - - pub fn iter(&self) -> impl Iterator { - self.map - .iter() - .filter(|(_, info)| info.count > 0) - .map(|(item, &BottomRefInfo { distance, .. })| (item, distance)) - } - - pub fn add_clonable(&mut self, item: &T, distance: u8) -> bool { - match self.map.raw_entry_mut(item) { - RawEntry::Occupied(mut e) => { - let info = e.get_mut(); - info.count += 1; - match info.count.cmp(&0) { - std::cmp::Ordering::Equal => { - e.remove(); - } - std::cmp::Ordering::Greater => { - if distance < info.distance { - info.distance = distance; - } - } - std::cmp::Ordering::Less => { - // We only track that for negative count tracking and no - // need to update the distance, it would reset anyway - // once we reach 0. - } - } - false - } - RawEntry::Vacant(e) => { - e.insert(item.clone(), BottomRefInfo { count: 1, distance }); - true - } - } - } - - pub fn remove_clonable(&mut self, item: &T) -> bool { - match self.map.raw_entry_mut(item) { - RawEntry::Occupied(mut e) => { - let info = e.get_mut(); - info.count -= 1; - if info.count == 0 { - e.remove(); - true - } else { - false - } - } - RawEntry::Vacant(e) => { - e.insert( - item.clone(), - BottomRefInfo { - count: -1, - distance: 0, - }, - ); - false - } - } - } - - pub fn into_counts(self) -> impl Iterator { - self.map.into_iter().map(|(item, info)| (item, info.count)) - } - - pub fn len(&self) -> usize { - self.map.len() - } -} - -/// Connection to upper bottom trees. It has two modes: A single bottom tree, -/// where the current left/smaller bottom tree is the left-most child. Or -/// multiple bottom trees, where the current left/smaller bottom tree is an -/// inner child (not left-most). -pub enum BottomConnection { - Left(Arc>), - Inner(DistanceCountMap>), -} - -impl BottomConnection { - pub fn new() -> Self { - Self::Inner(DistanceCountMap::new()) - } - - pub fn is_unset(&self) -> bool { - match self { - Self::Left(_) => false, - Self::Inner(list) => list.is_unset(), - } - } - - pub fn as_cloned_uppers(&self) -> BottomUppers { - match self { - Self::Left(upper) => BottomUppers::Left(upper.clone()), - Self::Inner(upper) => BottomUppers::Inner( - upper - .iter() - .map(|(item, distance)| (item.clone(), distance)) - .collect(), - ), - } - } - - #[must_use] - pub fn set_left_upper( - &mut self, - upper: &Arc>, - ) -> DistanceCountMap> { - match std::mem::replace(self, BottomConnection::Left(upper.clone())) { - BottomConnection::Left(_) => unreachable!("Can't have two left children"), - BottomConnection::Inner(old_inner) => old_inner, - } - } - - pub fn unset_left_upper(&mut self, upper: &Arc>) { - match std::mem::replace(self, BottomConnection::Inner(DistanceCountMap::new())) { - BottomConnection::Left(old_upper) => { - debug_assert!(Arc::ptr_eq(&old_upper, upper)); - } - BottomConnection::Inner(_) => unreachable!("Must that a left child"), - } - } -} - -impl BottomConnection { - pub fn child_change>( - &self, - aggregation_context: &C, - change: &C::ItemChange, - ) { - match self { - BottomConnection::Left(upper) => { - upper.child_change(aggregation_context, change); - } - BottomConnection::Inner(list) => { - for (BottomRef { upper }, _) in list.iter() { - upper.child_change(aggregation_context, change); - } - } - } - } - - pub fn get_root_info>( - &self, - aggregation_context: &C, - root_info_type: &C::RootInfoType, - mut result: C::RootInfo, - ) -> C::RootInfo { - match &self { - BottomConnection::Left(upper) => { - let info = upper.get_root_info(aggregation_context, root_info_type); - if aggregation_context.merge_root_info(&mut result, info) == ControlFlow::Break(()) - { - return result; - } - } - BottomConnection::Inner(list) => { - for (BottomRef { upper }, _) in list.iter() { - let info = upper.get_root_info(aggregation_context, root_info_type); - if aggregation_context.merge_root_info(&mut result, info) - == ControlFlow::Break(()) - { - return result; - } - } - } - } - result - } -} - -pub enum BottomUppers { - Left(Arc>), - Inner(StackVec<(BottomRef, u8)>), -} - -impl BottomUppers { - pub fn add_children_of_child<'a, C: AggregationContext>( - &self, - aggregation_context: &C, - children: impl IntoIterator + Clone, - ) where - I: 'a, - { - match self { - BottomUppers::Left(upper) => { - upper.add_children_of_child(aggregation_context, ChildLocation::Left, children, 0); - } - BottomUppers::Inner(list) => { - for &(BottomRef { ref upper }, nesting_level) in list { - upper.add_children_of_child( - aggregation_context, - ChildLocation::Inner, - children.clone(), - nesting_level + 1, - ); - } - } - } - } - - pub fn add_child_of_child>( - &self, - aggregation_context: &C, - child_of_child: &I, - ) { - match self { - BottomUppers::Left(upper) => { - upper.add_child_of_child( - aggregation_context, - ChildLocation::Left, - child_of_child, - 0, - ); - } - BottomUppers::Inner(list) => { - for &(BottomRef { ref upper }, nesting_level) in list.iter() { - upper.add_child_of_child( - aggregation_context, - ChildLocation::Inner, - child_of_child, - nesting_level + 1, - ); - } - } - } - } - - pub fn remove_child_of_child>( - &self, - aggregation_context: &C, - child_of_child: &I, - ) { - match self { - BottomUppers::Left(upper) => { - upper.remove_child_of_child(aggregation_context, child_of_child); - } - BottomUppers::Inner(list) => { - for (BottomRef { upper }, _) in list { - upper.remove_child_of_child(aggregation_context, child_of_child); - } - } - } - } - - pub fn remove_children_of_child<'a, C: AggregationContext>( - &self, - aggregation_context: &C, - children: impl IntoIterator + Clone, - ) where - I: 'a, - { - match self { - BottomUppers::Left(upper) => { - upper.remove_children_of_child(aggregation_context, children); - } - BottomUppers::Inner(list) => { - for (BottomRef { upper }, _) in list { - upper.remove_children_of_child(aggregation_context, children.clone()); - } - } - } - } - - pub fn child_change>( - &self, - aggregation_context: &C, - change: &C::ItemChange, - ) { - match self { - BottomUppers::Left(upper) => { - upper.child_change(aggregation_context, change); - } - BottomUppers::Inner(list) => { - for (BottomRef { upper }, _) in list { - upper.child_change(aggregation_context, change); - } - } - } - } - - pub fn get_root_info>( - &self, - aggregation_context: &C, - root_info_type: &C::RootInfoType, - mut result: C::RootInfo, - ) -> C::RootInfo { - match &self { - BottomUppers::Left(upper) => { - let info = upper.get_root_info(aggregation_context, root_info_type); - if aggregation_context.merge_root_info(&mut result, info) == ControlFlow::Break(()) - { - return result; - } - } - BottomUppers::Inner(list) => { - for (BottomRef { upper }, _) in list.iter() { - let info = upper.get_root_info(aggregation_context, root_info_type); - if aggregation_context.merge_root_info(&mut result, info) - == ControlFlow::Break(()) - { - return result; - } - } - } - } - result - } -} diff --git a/crates/turbo-tasks-memory/src/aggregation_tree/bottom_tree.rs b/crates/turbo-tasks-memory/src/aggregation_tree/bottom_tree.rs deleted file mode 100644 index 35b9472c7f4a9..0000000000000 --- a/crates/turbo-tasks-memory/src/aggregation_tree/bottom_tree.rs +++ /dev/null @@ -1,730 +0,0 @@ -use std::{hash::Hash, ops::ControlFlow, sync::Arc}; - -use nohash_hasher::{BuildNoHashHasher, IsEnabled}; -use parking_lot::{RwLock, RwLockReadGuard, RwLockWriteGuard}; -use ref_cast::RefCast; - -use super::{ - bottom_connection::BottomConnection, - inner_refs::{BottomRef, ChildLocation, TopRef}, - leaf::{ - add_inner_upper_to_item, bottom_tree, remove_inner_upper_from_item, - remove_left_upper_from_item, - }, - top_tree::TopTree, - AggregationContext, StackVec, CHILDREN_INNER_THRESHOLD, CONNECTIVITY_LIMIT, -}; -use crate::count_hash_set::{CountHashSet, RemoveIfEntryResult}; - -/// The bottom half of the aggregation tree. It aggregates items up the a -/// certain connectivity depending on the "height". Every level of the tree -/// aggregates the previous level. -pub struct BottomTree { - height: u8, - item: I, - state: RwLock>, -} - -pub struct BottomTreeState { - data: T, - bottom_upper: BottomConnection, - top_upper: CountHashSet, BuildNoHashHasher>>, - // TODO can this become negative? - following: CountHashSet>, -} - -impl BottomTree { - pub fn new(item: I, height: u8) -> Self { - Self { - height, - item, - state: RwLock::new(BottomTreeState { - data: T::default(), - bottom_upper: BottomConnection::new(), - top_upper: CountHashSet::new(), - following: CountHashSet::new(), - }), - } - } -} - -impl BottomTree { - pub fn add_children_of_child<'a, C: AggregationContext>( - self: &Arc, - aggregation_context: &C, - child_location: ChildLocation, - children: impl IntoIterator, - nesting_level: u8, - ) where - I: 'a, - { - match child_location { - ChildLocation::Left => { - // the left child has new children - // this means it's a inner child of this node - // We always want to aggregate over at least connectivity 1 - self.add_children_of_child_inner(aggregation_context, children, nesting_level); - } - ChildLocation::Inner => { - // the inner child has new children - // this means white children are inner children of this node - // and blue children need to propagate up - let mut children = children.into_iter().collect(); - if nesting_level > CONNECTIVITY_LIMIT { - self.add_children_of_child_following(aggregation_context, children); - return; - } - - self.add_children_of_child_if_following(&mut children); - self.add_children_of_child_inner(aggregation_context, children, nesting_level); - } - } - } - - fn add_children_of_child_if_following(&self, children: &mut StackVec<&I>) { - let mut state = self.state.write(); - children.retain(|&mut child| !state.following.add_if_entry(child)); - } - - fn add_children_of_child_following>( - self: &Arc, - aggregation_context: &C, - mut children: StackVec<&I>, - ) { - let mut state = self.state.write(); - children.retain(|&mut child| state.following.add_clonable(child)); - if children.is_empty() { - return; - } - let buttom_uppers = state.bottom_upper.as_cloned_uppers(); - let top_upper = state.top_upper.iter().cloned().collect::>(); - drop(state); - for TopRef { upper } in top_upper { - upper.add_children_of_child(aggregation_context, children.iter().copied()); - } - buttom_uppers.add_children_of_child(aggregation_context, children.iter().copied()); - } - - fn add_children_of_child_inner<'a, C: AggregationContext>( - self: &Arc, - aggregation_context: &C, - children: impl IntoIterator, - nesting_level: u8, - ) where - I: 'a, - { - let mut following = StackVec::default(); - if self.height == 0 { - for child in children { - let can_be_inner = - add_inner_upper_to_item(aggregation_context, child, self, nesting_level); - if !can_be_inner { - following.push(child); - } - } - } else { - for child in children { - let can_be_inner = bottom_tree(aggregation_context, child, self.height - 1) - .add_inner_bottom_tree_upper(aggregation_context, self, nesting_level); - if !can_be_inner { - following.push(child); - } - } - } - if !following.is_empty() { - self.add_children_of_child_following(aggregation_context, following); - } - } - - pub fn add_child_of_child>( - self: &Arc, - aggregation_context: &C, - child_location: ChildLocation, - child_of_child: &I, - nesting_level: u8, - ) { - debug_assert!(child_of_child != &self.item); - match child_location { - ChildLocation::Left => { - // the left child has a new child - // this means it's a inner child of this node - // We always want to aggregate over at least connectivity 1 - self.add_child_of_child_inner(aggregation_context, child_of_child, nesting_level); - } - ChildLocation::Inner => { - if nesting_level <= CONNECTIVITY_LIMIT { - // the inner child has a new child - // but it's not a blue node and we are not too deep - // this means it's a inner child of this node - // if it's not already a following child - if !self.add_child_of_child_if_following(child_of_child) { - self.add_child_of_child_inner( - aggregation_context, - child_of_child, - nesting_level, - ); - } - } else { - // the inner child has a new child - // this means we need to propagate the change up - // and store them in our own list - self.add_child_of_child_following(aggregation_context, child_of_child); - } - } - } - } - - fn add_child_of_child_if_following(&self, child_of_child: &I) -> bool { - let mut state = self.state.write(); - state.following.add_if_entry(child_of_child) - } - - fn add_child_of_child_following>( - self: &Arc, - aggregation_context: &C, - child_of_child: &I, - ) { - let mut state = self.state.write(); - if !state.following.add_clonable(child_of_child) { - // Already connect, nothing more to do - return; - } - - propagate_new_following_to_uppers(state, aggregation_context, child_of_child); - } - - fn add_child_of_child_inner>( - self: &Arc, - aggregation_context: &C, - child_of_child: &I, - nesting_level: u8, - ) { - let can_be_inner = if self.height == 0 { - add_inner_upper_to_item(aggregation_context, child_of_child, self, nesting_level) - } else { - bottom_tree(aggregation_context, child_of_child, self.height - 1) - .add_inner_bottom_tree_upper(aggregation_context, self, nesting_level) - }; - if !can_be_inner { - self.add_child_of_child_following(aggregation_context, child_of_child); - } - } - - pub fn remove_child_of_child>( - self: &Arc, - aggregation_context: &C, - child_of_child: &I, - ) { - if !self.remove_child_of_child_if_following(aggregation_context, child_of_child) { - self.remove_child_of_child_inner(aggregation_context, child_of_child); - } - } - - pub fn remove_children_of_child<'a, C: AggregationContext>( - self: &Arc, - aggregation_context: &C, - children: impl IntoIterator, - ) where - I: 'a, - { - let mut children = children.into_iter().collect(); - self.remove_children_of_child_if_following(aggregation_context, &mut children); - self.remove_children_of_child_inner(aggregation_context, children); - } - - fn remove_child_of_child_if_following>( - self: &Arc, - aggregation_context: &C, - child_of_child: &I, - ) -> bool { - let mut state = self.state.write(); - match state.following.remove_if_entry(child_of_child) { - RemoveIfEntryResult::PartiallyRemoved => return true, - RemoveIfEntryResult::NotPresent => return false, - RemoveIfEntryResult::Removed => {} - } - propagate_lost_following_to_uppers(state, aggregation_context, child_of_child); - true - } - - fn remove_children_of_child_if_following<'a, C: AggregationContext>( - self: &Arc, - aggregation_context: &C, - children: &mut Vec<&'a I>, - ) { - let mut state = self.state.write(); - let mut removed = StackVec::default(); - children.retain(|&child| match state.following.remove_if_entry(child) { - RemoveIfEntryResult::PartiallyRemoved => false, - RemoveIfEntryResult::NotPresent => true, - RemoveIfEntryResult::Removed => { - removed.push(child); - false - } - }); - if !removed.is_empty() { - propagate_lost_followings_to_uppers(state, aggregation_context, removed); - } - } - - fn remove_child_of_child_following>( - self: &Arc, - aggregation_context: &C, - child_of_child: &I, - ) -> bool { - let mut state = self.state.write(); - if !state.following.remove_clonable(child_of_child) { - // no present, nothing to do - return false; - } - propagate_lost_following_to_uppers(state, aggregation_context, child_of_child); - true - } - - fn remove_children_of_child_following>( - self: &Arc, - aggregation_context: &C, - mut children: StackVec<&I>, - ) { - let mut state = self.state.write(); - children.retain(|&mut child| state.following.remove_clonable(child)); - propagate_lost_followings_to_uppers(state, aggregation_context, children); - } - - fn remove_child_of_child_inner>( - self: &Arc, - aggregation_context: &C, - child_of_child: &I, - ) { - let can_remove_inner = if self.height == 0 { - remove_inner_upper_from_item(aggregation_context, child_of_child, self) - } else { - bottom_tree(aggregation_context, child_of_child, self.height - 1) - .remove_inner_bottom_tree_upper(aggregation_context, self) - }; - if !can_remove_inner { - self.remove_child_of_child_following(aggregation_context, child_of_child); - } - } - - fn remove_children_of_child_inner<'a, C: AggregationContext>( - self: &Arc, - aggregation_context: &C, - children: impl IntoIterator, - ) where - I: 'a, - { - let unremoveable: StackVec<_> = if self.height == 0 { - children - .into_iter() - .filter(|&child| !remove_inner_upper_from_item(aggregation_context, child, self)) - .collect() - } else { - children - .into_iter() - .filter(|&child| { - !bottom_tree(aggregation_context, child, self.height - 1) - .remove_inner_bottom_tree_upper(aggregation_context, self) - }) - .collect() - }; - if !unremoveable.is_empty() { - self.remove_children_of_child_following(aggregation_context, unremoveable); - } - } - - pub fn add_left_bottom_tree_upper>( - &self, - aggregation_context: &C, - upper: &Arc>, - ) { - let mut state = self.state.write(); - let old_inner = state.bottom_upper.set_left_upper(upper); - let add_change = aggregation_context.info_to_add_change(&state.data); - let children = state.following.iter().cloned().collect::>(); - - let remove_change = (!old_inner.is_unset()) - .then(|| aggregation_context.info_to_remove_change(&state.data)) - .flatten(); - - drop(state); - if let Some(change) = add_change { - upper.child_change(aggregation_context, &change); - } - if !children.is_empty() { - upper.add_children_of_child( - aggregation_context, - ChildLocation::Left, - children.iter(), - 1, - ); - } - - // Convert this node into a following node for all old (inner) uppers - // - // Old state: - // I1, I2 - // \ - // self - // Adding L as new left upper: - // I1, I2 L - // \ / - // self - // Final state: (I1 and I2 have L as following instead) - // I1, I2 ----> L - // / - // self - // I1 and I2 have "self" change removed since it's now part of L instead. - // L = upper, I1, I2 = old_inner - // - for (BottomRef { upper: old_upper }, count) in old_inner.into_counts() { - let item = &self.item; - old_upper.migrate_old_inner( - aggregation_context, - item, - count, - &remove_change, - &children, - ); - } - } - - pub fn migrate_old_inner>( - self: &Arc, - aggregation_context: &C, - item: &I, - count: isize, - remove_change: &Option, - following: &[I], - ) { - let mut state = self.state.write(); - if count > 0 { - // add as following - if state.following.add_count(item.clone(), count as usize) { - propagate_new_following_to_uppers(state, aggregation_context, item); - } else { - drop(state); - } - // remove from self - if let Some(change) = remove_change.as_ref() { - self.child_change(aggregation_context, change); - } - self.remove_children_of_child(aggregation_context, following); - } else { - // remove count from following instead - if state.following.remove_count(item.clone(), -count as usize) { - propagate_lost_following_to_uppers(state, aggregation_context, item); - } - } - } - - #[must_use] - pub fn add_inner_bottom_tree_upper>( - &self, - aggregation_context: &C, - upper: &Arc>, - nesting_level: u8, - ) -> bool { - let mut state = self.state.write(); - let number_of_following = state.following.len(); - let BottomConnection::Inner(inner) = &mut state.bottom_upper else { - return false; - }; - if inner.len() * number_of_following > CHILDREN_INNER_THRESHOLD { - return false; - }; - let new = inner.add_clonable(BottomRef::ref_cast(upper), nesting_level); - if new { - if let Some(change) = aggregation_context.info_to_add_change(&state.data) { - upper.child_change(aggregation_context, &change); - } - let children = state.following.iter().cloned().collect::>(); - drop(state); - if !children.is_empty() { - upper.add_children_of_child( - aggregation_context, - ChildLocation::Inner, - &children, - nesting_level + 1, - ); - } - } - true - } - - pub fn remove_left_bottom_tree_upper>( - self: &Arc, - aggregation_context: &C, - upper: &Arc>, - ) { - let mut state = self.state.write(); - state.bottom_upper.unset_left_upper(upper); - if let Some(change) = aggregation_context.info_to_remove_change(&state.data) { - upper.child_change(aggregation_context, &change); - } - let following = state.following.iter().cloned().collect::>(); - if state.top_upper.is_empty() { - drop(state); - self.remove_self_from_lower(aggregation_context); - } else { - drop(state); - } - upper.remove_children_of_child(aggregation_context, &following); - } - - #[must_use] - pub fn remove_inner_bottom_tree_upper>( - &self, - aggregation_context: &C, - upper: &Arc>, - ) -> bool { - let mut state = self.state.write(); - let BottomConnection::Inner(inner) = &mut state.bottom_upper else { - return false; - }; - let removed = inner.remove_clonable(BottomRef::ref_cast(upper)); - if removed { - let remove_change = aggregation_context.info_to_remove_change(&state.data); - let following = state.following.iter().cloned().collect::>(); - drop(state); - if let Some(change) = remove_change { - upper.child_change(aggregation_context, &change); - } - upper.remove_children_of_child(aggregation_context, &following); - } - true - } - - pub fn add_top_tree_upper>( - &self, - aggregation_context: &C, - upper: &Arc>, - ) { - let mut state = self.state.write(); - let new = state.top_upper.add_clonable(TopRef::ref_cast(upper)); - if new { - if let Some(change) = aggregation_context.info_to_add_change(&state.data) { - upper.child_change(aggregation_context, &change); - } - for following in state.following.iter() { - upper.add_child_of_child(aggregation_context, following); - } - } - } - - #[allow(dead_code)] - pub fn remove_top_tree_upper>( - self: &Arc, - aggregation_context: &C, - upper: &Arc>, - ) { - let mut state = self.state.write(); - let removed = state.top_upper.remove_clonable(TopRef::ref_cast(upper)); - if removed { - if let Some(change) = aggregation_context.info_to_remove_change(&state.data) { - upper.child_change(aggregation_context, &change); - } - for following in state.following.iter() { - upper.remove_child_of_child(aggregation_context, following); - } - if state.top_upper.is_empty() - && !matches!(state.bottom_upper, BottomConnection::Left(_)) - { - drop(state); - self.remove_self_from_lower(aggregation_context); - } - } - } - - fn remove_self_from_lower( - self: &Arc, - aggregation_context: &impl AggregationContext, - ) { - if self.height == 0 { - remove_left_upper_from_item(aggregation_context, &self.item, self); - } else { - bottom_tree(aggregation_context, &self.item, self.height - 1) - .remove_left_bottom_tree_upper(aggregation_context, self); - } - } - - pub fn child_change>( - &self, - aggregation_context: &C, - change: &C::ItemChange, - ) { - let mut state = self.state.write(); - let change = aggregation_context.apply_change(&mut state.data, change); - let state = RwLockWriteGuard::downgrade(state); - propagate_change_to_upper(&state, aggregation_context, change); - } - - pub fn get_root_info>( - &self, - aggregation_context: &C, - root_info_type: &C::RootInfoType, - ) -> C::RootInfo { - let mut result = aggregation_context.new_root_info(root_info_type); - let top_uppers = { - let state = self.state.read(); - state.top_upper.iter().cloned().collect::>() - }; - for TopRef { upper } in top_uppers.iter() { - let info = upper.get_root_info(aggregation_context, root_info_type); - if aggregation_context.merge_root_info(&mut result, info) == ControlFlow::Break(()) { - return result; - } - } - let bottom_uppers = { - let state = self.state.read(); - state.bottom_upper.as_cloned_uppers() - }; - bottom_uppers.get_root_info(aggregation_context, root_info_type, result) - } -} - -fn propagate_lost_following_to_uppers( - state: RwLockWriteGuard<'_, BottomTreeState>, - aggregation_context: &C, - child_of_child: &C::ItemRef, -) { - let bottom_uppers = state.bottom_upper.as_cloned_uppers(); - let top_upper = state.top_upper.iter().cloned().collect::>(); - drop(state); - for TopRef { upper } in top_upper { - upper.remove_child_of_child(aggregation_context, child_of_child); - } - bottom_uppers.remove_child_of_child(aggregation_context, child_of_child); -} - -fn propagate_lost_followings_to_uppers<'a, C: AggregationContext>( - state: RwLockWriteGuard<'_, BottomTreeState>, - aggregation_context: &C, - children: impl IntoIterator + Clone, -) where - C::ItemRef: 'a, -{ - let bottom_uppers = state.bottom_upper.as_cloned_uppers(); - let top_upper = state.top_upper.iter().cloned().collect::>(); - drop(state); - for TopRef { upper } in top_upper { - upper.remove_children_of_child(aggregation_context, children.clone()); - } - bottom_uppers.remove_children_of_child(aggregation_context, children); -} - -fn propagate_new_following_to_uppers( - state: RwLockWriteGuard<'_, BottomTreeState>, - aggregation_context: &C, - child_of_child: &C::ItemRef, -) { - let bottom_uppers = state.bottom_upper.as_cloned_uppers(); - let top_upper = state.top_upper.iter().cloned().collect::>(); - drop(state); - for TopRef { upper } in top_upper { - upper.add_child_of_child(aggregation_context, child_of_child); - } - bottom_uppers.add_child_of_child(aggregation_context, child_of_child); -} - -fn propagate_change_to_upper( - state: &RwLockReadGuard>, - aggregation_context: &C, - change: Option, -) { - let Some(change) = change else { - return; - }; - state - .bottom_upper - .child_change(aggregation_context, &change); - for TopRef { upper } in state.top_upper.iter() { - upper.child_change(aggregation_context, &change); - } -} - -#[allow(clippy::disallowed_methods)] // Allow VecDeque::new() in this test -#[cfg(test)] -fn visit_graph( - aggregation_context: &C, - entry: &C::ItemRef, - height: u8, -) -> (usize, usize) { - use std::collections::{HashSet, VecDeque}; - let mut queue = VecDeque::new(); - let mut visited = HashSet::new(); - visited.insert(entry.clone()); - queue.push_back(entry.clone()); - let mut edges = 0; - while let Some(item) = queue.pop_front() { - let tree = bottom_tree(aggregation_context, &item, height); - let state = tree.state.read(); - for next in state.following.iter() { - edges += 1; - if visited.insert(next.clone()) { - queue.push_back(next.clone()); - } - } - } - (visited.len(), edges) -} - -#[allow(clippy::disallowed_methods)] // Allow VecDeque::new() in this test -#[cfg(test)] -pub fn print_graph( - aggregation_context: &C, - entry: &C::ItemRef, - height: u8, - color_upper: bool, - name_fn: impl Fn(&C::ItemRef) -> String, -) { - use std::{ - collections::{HashSet, VecDeque}, - fmt::Write, - }; - let (nodes, edges) = visit_graph(aggregation_context, entry, height); - if !color_upper { - print!("subgraph cluster_{} {{", height); - print!( - "label = \"Level {}\\n{} nodes, {} edges\";", - height, nodes, edges - ); - print!("color = \"black\";"); - } - let mut edges = String::new(); - let mut queue = VecDeque::new(); - let mut visited = HashSet::new(); - visited.insert(entry.clone()); - queue.push_back(entry.clone()); - while let Some(item) = queue.pop_front() { - let tree = bottom_tree(aggregation_context, &item, height); - let name = name_fn(&item); - let label = name.to_string(); - let state = tree.state.read(); - if color_upper { - print!(r#""{} {}" [color=red];"#, height - 1, name); - } else { - print!(r#""{} {}" [label="{}"];"#, height, name, label); - } - for next in state.following.iter() { - if !color_upper { - write!( - edges, - r#""{} {}" -> "{} {}";"#, - height, - name, - height, - name_fn(next) - ) - .unwrap(); - } - if visited.insert(next.clone()) { - queue.push_back(next.clone()); - } - } - } - if !color_upper { - println!("}}"); - println!("{}", edges); - } -} diff --git a/crates/turbo-tasks-memory/src/aggregation_tree/inner_refs.rs b/crates/turbo-tasks-memory/src/aggregation_tree/inner_refs.rs deleted file mode 100644 index 92693d65f3a7c..0000000000000 --- a/crates/turbo-tasks-memory/src/aggregation_tree/inner_refs.rs +++ /dev/null @@ -1,79 +0,0 @@ -use std::{ - hash::{Hash, Hasher}, - sync::Arc, -}; - -use nohash_hasher::IsEnabled; -use ref_cast::RefCast; - -use super::{bottom_tree::BottomTree, top_tree::TopTree}; - -#[derive(Clone, Copy, PartialEq, Eq, Hash)] -pub enum ChildLocation { - // Left-most child - Left, - // Inner child, not left-most - Inner, -} - -/// A reference to a [TopTree]. -#[derive(RefCast)] -#[repr(transparent)] -pub struct TopRef { - pub upper: Arc>, -} - -impl IsEnabled for TopRef {} - -impl Hash for TopRef { - fn hash(&self, state: &mut H) { - Arc::as_ptr(&self.upper).hash(state); - } -} - -impl PartialEq for TopRef { - fn eq(&self, other: &Self) -> bool { - Arc::ptr_eq(&self.upper, &other.upper) - } -} - -impl Eq for TopRef {} - -impl Clone for TopRef { - fn clone(&self) -> Self { - Self { - upper: self.upper.clone(), - } - } -} - -/// A reference to a [BottomTree]. -#[derive(RefCast)] -#[repr(transparent)] -pub struct BottomRef { - pub upper: Arc>, -} - -impl Hash for BottomRef { - fn hash(&self, state: &mut H) { - Arc::as_ptr(&self.upper).hash(state); - } -} - -impl IsEnabled for BottomRef {} - -impl PartialEq for BottomRef { - fn eq(&self, other: &Self) -> bool { - Arc::ptr_eq(&self.upper, &other.upper) - } -} - -impl Eq for BottomRef {} - -impl Clone for BottomRef { - fn clone(&self) -> Self { - Self { - upper: self.upper.clone(), - } - } -} diff --git a/crates/turbo-tasks-memory/src/aggregation_tree/leaf.rs b/crates/turbo-tasks-memory/src/aggregation_tree/leaf.rs deleted file mode 100644 index 0166e66d6a6e0..0000000000000 --- a/crates/turbo-tasks-memory/src/aggregation_tree/leaf.rs +++ /dev/null @@ -1,403 +0,0 @@ -use std::{hash::Hash, sync::Arc}; - -use auto_hash_map::AutoSet; -use nohash_hasher::IsEnabled; -use ref_cast::RefCast; -use tracing::Level; - -use super::{ - bottom_connection::{BottomConnection, DistanceCountMap}, - bottom_tree::BottomTree, - inner_refs::{BottomRef, ChildLocation}, - top_tree::TopTree, - AggregationContext, AggregationItemLock, LargeStackVec, CHILDREN_INNER_THRESHOLD, -}; - -/// The leaf of the aggregation tree. It's usually stored inside of the nodes -/// that should be aggregated by the aggregation tree. It caches [TopTree]s and -/// [BottomTree]s created from that node. And it also stores the upper bottom -/// trees. -pub struct AggregationTreeLeaf { - top_trees: Vec>>>, - bottom_trees: Vec>>>, - upper: BottomConnection, -} - -impl AggregationTreeLeaf { - pub fn new() -> Self { - Self { - top_trees: Vec::new(), - bottom_trees: Vec::new(), - upper: BottomConnection::new(), - } - } - - /// Prepares the addition of new children. It returns a closure that should - /// be executed outside of the leaf lock. - #[allow(unused)] - pub fn add_children_job<'a, C: AggregationContext>( - &self, - aggregation_context: &'a C, - children: Vec, - ) -> impl FnOnce() + 'a - where - I: 'a, - T: 'a, - { - let uppers = self.upper.as_cloned_uppers(); - move || { - uppers.add_children_of_child(aggregation_context, &children); - } - } - - /// Prepares the addition of a new child. It returns a closure that should - /// be executed outside of the leaf lock. - pub fn add_child_job<'a, C: AggregationContext>( - &self, - aggregation_context: &'a C, - child: &'a I, - ) -> impl FnOnce() + 'a - where - T: 'a, - { - let uppers = self.upper.as_cloned_uppers(); - move || { - uppers.add_child_of_child(aggregation_context, child); - } - } - - /// Removes a child. - pub fn remove_child>( - &self, - aggregation_context: &C, - child: &I, - ) { - self.upper - .as_cloned_uppers() - .remove_child_of_child(aggregation_context, child); - } - - /// Prepares the removal of a child. It returns a closure that should be - /// executed outside of the leaf lock. - pub fn remove_children_job< - 'a, - C: AggregationContext, - H, - const N: usize, - >( - &self, - aggregation_context: &'a C, - children: AutoSet, - ) -> impl FnOnce() + 'a - where - T: 'a, - I: 'a, - H: 'a, - { - let uppers = self.upper.as_cloned_uppers(); - move || uppers.remove_children_of_child(aggregation_context, children.iter()) - } - - /// Communicates a change on the leaf to updated aggregated nodes. Prefer - /// [Self::change_job] to avoid leaf locking. - pub fn change>( - &self, - aggregation_context: &C, - change: &C::ItemChange, - ) { - self.upper.child_change(aggregation_context, change); - } - - /// Prepares the communication of a change on the leaf to updated aggregated - /// nodes. It returns a closure that should be executed outside of the leaf - /// lock. - pub fn change_job<'a, C: AggregationContext>( - &self, - aggregation_context: &'a C, - change: C::ItemChange, - ) -> impl FnOnce() + 'a - where - I: 'a, - T: 'a, - { - let uppers = self.upper.as_cloned_uppers(); - move || { - uppers.child_change(aggregation_context, &change); - } - } - - /// Captures information about the aggregation tree roots. - pub fn get_root_info>( - &self, - aggregation_context: &C, - root_info_type: &C::RootInfoType, - ) -> C::RootInfo { - self.upper.get_root_info( - aggregation_context, - root_info_type, - aggregation_context.new_root_info(root_info_type), - ) - } - - pub fn has_upper(&self) -> bool { - !self.upper.is_unset() - } -} - -fn get_or_create_in_vec( - vec: &mut Vec>, - index: usize, - create: impl FnOnce() -> T, -) -> (&mut T, bool) { - if vec.len() <= index { - vec.resize_with(index + 1, || None); - } - let item = &mut vec[index]; - if item.is_none() { - *item = Some(create()); - (item.as_mut().unwrap(), true) - } else { - (item.as_mut().unwrap(), false) - } -} - -#[tracing::instrument(level = Level::TRACE, skip(aggregation_context, reference))] -pub fn top_tree( - aggregation_context: &C, - reference: &C::ItemRef, - depth: u8, -) -> Arc> { - let new_top_tree = { - let mut item = aggregation_context.item(reference); - let leaf = item.leaf(); - let (tree, new) = get_or_create_in_vec(&mut leaf.top_trees, depth as usize, || { - Arc::new(TopTree::new(depth)) - }); - if !new { - return tree.clone(); - } - tree.clone() - }; - let bottom_tree = bottom_tree(aggregation_context, reference, depth + 4); - bottom_tree.add_top_tree_upper(aggregation_context, &new_top_tree); - new_top_tree -} - -pub fn bottom_tree( - aggregation_context: &C, - reference: &C::ItemRef, - height: u8, -) -> Arc> { - let _span; - let new_bottom_tree; - let mut result = None; - { - let mut item = aggregation_context.item(reference); - let leaf = item.leaf(); - let (tree, new) = get_or_create_in_vec(&mut leaf.bottom_trees, height as usize, || { - Arc::new(BottomTree::new(reference.clone(), height)) - }); - if !new { - return tree.clone(); - } - new_bottom_tree = tree.clone(); - _span = (height > 2).then(|| tracing::trace_span!("bottom_tree", height).entered()); - - if height == 0 { - result = Some(add_left_upper_to_item_step_1::( - &mut item, - &new_bottom_tree, - )); - } - } - if let Some(result) = result { - add_left_upper_to_item_step_2(aggregation_context, reference, &new_bottom_tree, result); - } - if height != 0 { - bottom_tree(aggregation_context, reference, height - 1) - .add_left_bottom_tree_upper(aggregation_context, &new_bottom_tree); - } - new_bottom_tree -} - -#[must_use] -pub fn add_inner_upper_to_item( - aggregation_context: &C, - reference: &C::ItemRef, - upper: &Arc>, - nesting_level: u8, -) -> bool { - let (change, children) = { - let mut item = aggregation_context.item(reference); - let number_of_children = item.number_of_children(); - let leaf = item.leaf(); - let BottomConnection::Inner(inner) = &mut leaf.upper else { - return false; - }; - if inner.len() * number_of_children > CHILDREN_INNER_THRESHOLD { - return false; - } - let new = inner.add_clonable(BottomRef::ref_cast(upper), nesting_level); - if new { - let change = item.get_add_change(); - ( - change, - item.children() - .map(|r| r.into_owned()) - .collect::>(), - ) - } else { - return true; - } - }; - if let Some(change) = change { - upper.child_change(aggregation_context, &change); - } - if !children.is_empty() { - upper.add_children_of_child( - aggregation_context, - ChildLocation::Inner, - &children, - nesting_level + 1, - ) - } - true -} - -struct AddLeftUpperIntermediateResult( - Option, - LargeStackVec, - DistanceCountMap>, - Option, -); - -#[must_use] -fn add_left_upper_to_item_step_1( - item: &mut C::ItemLock<'_>, - upper: &Arc>, -) -> AddLeftUpperIntermediateResult { - let old_inner = item.leaf().upper.set_left_upper(upper); - let remove_change_for_old_inner = (!old_inner.is_unset()) - .then(|| item.get_remove_change()) - .flatten(); - let children = item.children().map(|r| r.into_owned()).collect(); - AddLeftUpperIntermediateResult( - item.get_add_change(), - children, - old_inner, - remove_change_for_old_inner, - ) -} - -fn add_left_upper_to_item_step_2( - aggregation_context: &C, - reference: &C::ItemRef, - upper: &Arc>, - step_1_result: AddLeftUpperIntermediateResult, -) { - let AddLeftUpperIntermediateResult(change, children, old_inner, remove_change_for_old_inner) = - step_1_result; - if let Some(change) = change { - upper.child_change(aggregation_context, &change); - } - if !children.is_empty() { - upper.add_children_of_child(aggregation_context, ChildLocation::Left, &children, 1) - } - for (BottomRef { upper: old_upper }, count) in old_inner.into_counts() { - old_upper.migrate_old_inner( - aggregation_context, - reference, - count, - &remove_change_for_old_inner, - &children, - ); - } -} - -pub fn remove_left_upper_from_item( - aggregation_context: &C, - reference: &C::ItemRef, - upper: &Arc>, -) { - let mut item = aggregation_context.item(reference); - let leaf = &mut item.leaf(); - leaf.upper.unset_left_upper(upper); - let change = item.get_remove_change(); - let children = item.children().map(|r| r.into_owned()).collect::>(); - drop(item); - if let Some(change) = change { - upper.child_change(aggregation_context, &change); - } - for child in children { - upper.remove_child_of_child(aggregation_context, &child) - } -} - -#[must_use] -pub fn remove_inner_upper_from_item( - aggregation_context: &C, - reference: &C::ItemRef, - upper: &Arc>, -) -> bool { - let mut item = aggregation_context.item(reference); - let BottomConnection::Inner(inner) = &mut item.leaf().upper else { - return false; - }; - if !inner.remove_clonable(BottomRef::ref_cast(upper)) { - // Nothing to do - return true; - } - let change = item.get_remove_change(); - let children = item - .children() - .map(|r| r.into_owned()) - .collect::>(); - drop(item); - - if let Some(change) = change { - upper.child_change(aggregation_context, &change); - } - for child in children { - upper.remove_child_of_child(aggregation_context, &child) - } - true -} - -/// Checks thresholds for an item to ensure the aggregation graph stays -/// well-formed. Run this before adding a child to an item. Returns a closure -/// that should be executed outside of the leaf lock. -pub fn ensure_thresholds<'a, C: AggregationContext>( - aggregation_context: &'a C, - item: &mut C::ItemLock<'_>, -) -> Option { - let mut result = None; - - let number_of_total_children = item.number_of_children(); - let reference = item.reference().clone(); - let leaf = item.leaf(); - if let BottomConnection::Inner(list) = &leaf.upper { - if list.len() * number_of_total_children > CHILDREN_INNER_THRESHOLD { - let (tree, new) = get_or_create_in_vec(&mut leaf.bottom_trees, 0, || { - Arc::new(BottomTree::new(reference.clone(), 0)) - }); - debug_assert!(new); - let new_bottom_tree = tree.clone(); - result = Some(( - add_left_upper_to_item_step_1::(item, &new_bottom_tree), - reference, - new_bottom_tree, - )); - } - } - result.map(|(result, reference, new_bottom_tree)| { - move || { - let _span = tracing::trace_span!("aggregation_tree::reorganize").entered(); - add_left_upper_to_item_step_2( - aggregation_context, - &reference, - &new_bottom_tree, - result, - ); - } - }) -} diff --git a/crates/turbo-tasks-memory/src/aggregation_tree/mod.rs b/crates/turbo-tasks-memory/src/aggregation_tree/mod.rs deleted file mode 100644 index cb5e449176772..0000000000000 --- a/crates/turbo-tasks-memory/src/aggregation_tree/mod.rs +++ /dev/null @@ -1,150 +0,0 @@ -//! The module implements a datastructure that aggregates a "forest" into less -//! nodes. For any node one can ask for a single aggregated version of all -//! children on that node. Changes the the forest will propagate up the -//! aggregation tree to keep it up to date. So asking of an aggregated -//! information is cheap and one can even wait for aggregated info to change. -//! -//! The aggregation will try to reuse aggregated nodes on every level to reduce -//! memory and cpu usage of propagating changes. The tree structure is designed -//! for multi-thread usage. -//! -//! The aggregation tree is build out of two halfs. The top tree and the bottom -//! tree. One node of the bottom tree can aggregate items of connectivity -//! 2^height. It will do that by having bottom trees of height - 1 as children. -//! One node of the top tree can aggregate items of any connectivity. It will do -//! that by having a bottom tree of height = depth as a child and top trees of -//! depth + 1 as children. So it's basically a linked list of bottom trees of -//! increasing height. Any top or bottom node can be shared between multiple -//! parents. -//! -//! Notations: -//! - parent/child: Relationship in the original forest resp. the aggregated -//! version of the relationships. -//! - upper: Relationship to a aggregated node in a higher level (more -//! aggregated). Since all communication is strictly upwards there is no down -//! relationship for that. - -mod bottom_connection; -mod bottom_tree; -mod inner_refs; -mod leaf; -#[cfg(test)] -mod tests; -mod top_tree; - -use std::{borrow::Cow, hash::Hash, ops::ControlFlow, sync::Arc}; - -use nohash_hasher::IsEnabled; -use smallvec::SmallVec; - -use self::{leaf::top_tree, top_tree::TopTree}; -pub use self::{ - leaf::{ensure_thresholds, AggregationTreeLeaf}, - top_tree::AggregationInfoGuard, -}; - -/// The maximum connectivity of one layer of bottom tree. -const CONNECTIVITY_LIMIT: u8 = 7; - -/// The maximum of number of children muliplied by number of upper bottom trees. -/// When reached the parent of the children will form a new bottom tree. -const CHILDREN_INNER_THRESHOLD: usize = 2000; - -type StackVec = SmallVec<[I; 16]>; -type LargeStackVec = SmallVec<[I; 32]>; - -/// The context trait which defines how the aggregation tree should behave. -pub trait AggregationContext { - type ItemLock<'a>: AggregationItemLock< - ItemRef = Self::ItemRef, - Info = Self::Info, - ItemChange = Self::ItemChange, - > - where - Self: 'a; - type Info: Default; - type ItemChange; - type ItemRef: Eq + Hash + Clone + IsEnabled; - type RootInfo; - type RootInfoType; - - /// Gets mutable access to an item. - fn item<'a>(&'a self, reference: &Self::ItemRef) -> Self::ItemLock<'a>; - - /// Apply a changeset to an aggregated info object. Returns a new changeset - /// that should be applied to the next aggregation level. Might return None, - /// if no change should be applied to the next level. - fn apply_change( - &self, - info: &mut Self::Info, - change: &Self::ItemChange, - ) -> Option; - - /// Creates a changeset from an aggregated info object, that represents - /// adding the aggregated node to an aggregated node of the next level. - fn info_to_add_change(&self, info: &Self::Info) -> Option; - /// Creates a changeset from an aggregated info object, that represents - /// removing the aggregated node from an aggregated node of the next level. - fn info_to_remove_change(&self, info: &Self::Info) -> Option; - - /// Initializes a new empty root info object. - fn new_root_info(&self, root_info_type: &Self::RootInfoType) -> Self::RootInfo; - /// Creates a new root info object from an aggregated info object. This is - /// only called on the root of the aggregation tree. - fn info_to_root_info( - &self, - info: &Self::Info, - root_info_type: &Self::RootInfoType, - ) -> Self::RootInfo; - /// Merges two root info objects. Can optionally break the root info - /// gathering which will return this root info object as final result. - fn merge_root_info( - &self, - root_info: &mut Self::RootInfo, - other: Self::RootInfo, - ) -> ControlFlow<()>; -} - -/// A lock on a single item. -pub trait AggregationItemLock { - type Info; - type ItemRef: Clone + IsEnabled; - type ItemChange; - type ChildrenIter<'a>: Iterator> + 'a - where - Self: 'a; - /// Returns a reference to the item. - fn reference(&self) -> &Self::ItemRef; - /// Get mutable access to the leaf info. - fn leaf(&mut self) -> &mut AggregationTreeLeaf; - /// Returns the number of children. - fn number_of_children(&self) -> usize; - /// Returns an iterator over the children. - fn children(&self) -> Self::ChildrenIter<'_>; - /// Returns a changeset that represents the addition of the item. - fn get_add_change(&self) -> Option; - /// Returns a changeset that represents the removal of the item. - fn get_remove_change(&self) -> Option; -} - -/// Gives an reference to the root aggregated info for a given item. -pub fn aggregation_info( - aggregation_context: &C, - reference: &C::ItemRef, -) -> AggregationInfoReference { - AggregationInfoReference { - tree: top_tree(aggregation_context, reference, 0), - } -} - -/// A reference to the root aggregated info of a node. -pub struct AggregationInfoReference { - tree: Arc>, -} - -impl AggregationInfoReference { - /// Locks the info and gives mutable access to it. - pub fn lock(&self) -> AggregationInfoGuard { - self.tree.lock_info() - } -} diff --git a/crates/turbo-tasks-memory/src/aggregation_tree/tests.rs b/crates/turbo-tasks-memory/src/aggregation_tree/tests.rs deleted file mode 100644 index 53c73d1a6513c..0000000000000 --- a/crates/turbo-tasks-memory/src/aggregation_tree/tests.rs +++ /dev/null @@ -1,600 +0,0 @@ -use std::{ - borrow::Cow, - hash::Hash, - sync::{ - atomic::{AtomicU32, Ordering}, - Arc, - }, - time::Instant, -}; - -use nohash_hasher::IsEnabled; -use parking_lot::{Mutex, MutexGuard}; -use ref_cast::RefCast; - -use super::{aggregation_info, AggregationContext, AggregationItemLock, AggregationTreeLeaf}; -use crate::aggregation_tree::{bottom_tree::print_graph, leaf::ensure_thresholds}; - -struct Node { - inner: Mutex, -} - -impl Node { - fn incr(&self, aggregation_context: &NodeAggregationContext) { - let mut guard = self.inner.lock(); - guard.value += 10000; - guard - .aggregation_leaf - .change(aggregation_context, &Change { value: 10000 }); - } -} - -#[derive(Copy, Clone)] -struct Change { - value: i32, -} - -impl Change { - fn is_empty(&self) -> bool { - self.value == 0 - } -} - -struct NodeInner { - children: Vec>, - aggregation_leaf: AggregationTreeLeaf, - value: u32, -} - -struct NodeAggregationContext<'a> { - additions: AtomicU32, - #[allow(dead_code)] - something_with_lifetime: &'a u32, - add_value: bool, -} - -#[derive(Clone, RefCast)] -#[repr(transparent)] -struct NodeRef(Arc); - -impl Hash for NodeRef { - fn hash(&self, state: &mut H) { - Arc::as_ptr(&self.0).hash(state); - } -} - -impl IsEnabled for NodeRef {} - -impl PartialEq for NodeRef { - fn eq(&self, other: &Self) -> bool { - Arc::ptr_eq(&self.0, &other.0) - } -} - -impl Eq for NodeRef {} - -struct NodeGuard { - guard: MutexGuard<'static, NodeInner>, - node: Arc, -} - -impl NodeGuard { - unsafe fn new(guard: MutexGuard<'_, NodeInner>, node: Arc) -> Self { - NodeGuard { - guard: unsafe { std::mem::transmute(guard) }, - node, - } - } -} - -impl AggregationItemLock for NodeGuard { - type Info = Aggregated; - type ItemRef = NodeRef; - type ItemChange = Change; - type ChildrenIter<'a> = impl Iterator> + 'a; - - fn reference(&self) -> &Self::ItemRef { - NodeRef::ref_cast(&self.node) - } - - fn leaf(&mut self) -> &mut AggregationTreeLeaf { - &mut self.guard.aggregation_leaf - } - - fn number_of_children(&self) -> usize { - self.guard.children.len() - } - - fn children(&self) -> Self::ChildrenIter<'_> { - self.guard - .children - .iter() - .map(|child| Cow::Owned(NodeRef(child.clone()))) - } - - fn get_remove_change(&self) -> Option { - let change = Change { - value: -(self.guard.value as i32), - }; - if change.is_empty() { - None - } else { - Some(change) - } - } - - fn get_add_change(&self) -> Option { - let change = Change { - value: self.guard.value as i32, - }; - if change.is_empty() { - None - } else { - Some(change) - } - } -} - -impl<'a> AggregationContext for NodeAggregationContext<'a> { - type ItemLock<'l> = NodeGuard where Self: 'l; - type Info = Aggregated; - type ItemRef = NodeRef; - type ItemChange = Change; - - fn item<'b>(&'b self, reference: &Self::ItemRef) -> Self::ItemLock<'b> { - let r = reference.0.clone(); - let guard = reference.0.inner.lock(); - unsafe { NodeGuard::new(guard, r) } - } - - fn apply_change(&self, info: &mut Aggregated, change: &Change) -> Option { - if info.value != 0 { - self.additions.fetch_add(1, Ordering::SeqCst); - } - if self.add_value { - info.value += change.value; - } - Some(*change) - } - - fn info_to_add_change(&self, info: &Self::Info) -> Option { - let change = Change { value: info.value }; - if change.is_empty() { - None - } else { - Some(change) - } - } - - fn info_to_remove_change(&self, info: &Self::Info) -> Option { - let change = Change { value: -info.value }; - if change.is_empty() { - None - } else { - Some(change) - } - } - - type RootInfo = bool; - - type RootInfoType = (); - - fn new_root_info(&self, root_info_type: &Self::RootInfoType) -> Self::RootInfo { - #[allow(clippy::match_single_binding)] - match root_info_type { - () => false, - } - } - - fn info_to_root_info( - &self, - info: &Self::Info, - root_info_type: &Self::RootInfoType, - ) -> Self::RootInfo { - #[allow(clippy::match_single_binding)] - match root_info_type { - () => info.active, - } - } - - fn merge_root_info( - &self, - root_info: &mut Self::RootInfo, - other: Self::RootInfo, - ) -> std::ops::ControlFlow<()> { - if other { - *root_info = true; - std::ops::ControlFlow::Break(()) - } else { - std::ops::ControlFlow::Continue(()) - } - } -} - -#[derive(Default)] -struct Aggregated { - value: i32, - active: bool, -} - -#[test] -fn chain() { - let something_with_lifetime = 0; - let ctx = NodeAggregationContext { - additions: AtomicU32::new(0), - something_with_lifetime: &something_with_lifetime, - add_value: true, - }; - let leaf = Arc::new(Node { - inner: Mutex::new(NodeInner { - children: vec![], - aggregation_leaf: AggregationTreeLeaf::new(), - value: 10000, - }), - }); - let mut current = leaf.clone(); - for i in 1..=100 { - current = Arc::new(Node { - inner: Mutex::new(NodeInner { - children: vec![current], - aggregation_leaf: AggregationTreeLeaf::new(), - value: i, - }), - }); - } - let current = NodeRef(current); - - { - let root_info = leaf.inner.lock().aggregation_leaf.get_root_info(&ctx, &()); - assert!(!root_info); - } - - { - let aggregated = aggregation_info(&ctx, ¤t); - assert_eq!(aggregated.lock().value, 15050); - } - assert_eq!(ctx.additions.load(Ordering::SeqCst), 100); - ctx.additions.store(0, Ordering::SeqCst); - - print(&ctx, ¤t); - - { - let root_info = leaf.inner.lock().aggregation_leaf.get_root_info(&ctx, &()); - assert!(!root_info); - } - - leaf.incr(&ctx); - // The change need to propagate through 5 top trees and 5 bottom trees - assert_eq!(ctx.additions.load(Ordering::SeqCst), 6); - ctx.additions.store(0, Ordering::SeqCst); - - { - let aggregated = aggregation_info(&ctx, ¤t); - let mut aggregated = aggregated.lock(); - assert_eq!(aggregated.value, 25050); - aggregated.active = true; - } - assert_eq!(ctx.additions.load(Ordering::SeqCst), 0); - ctx.additions.store(0, Ordering::SeqCst); - - { - let root_info = leaf.inner.lock().aggregation_leaf.get_root_info(&ctx, &()); - assert!(root_info); - } - - let i = 101; - let current = Arc::new(Node { - inner: Mutex::new(NodeInner { - children: vec![current.0], - aggregation_leaf: AggregationTreeLeaf::new(), - value: i, - }), - }); - let current = NodeRef(current); - - { - let aggregated = aggregation_info(&ctx, ¤t); - let aggregated = aggregated.lock(); - assert_eq!(aggregated.value, 25151); - } - // This should be way less the 100 to prove that we are reusing trees - assert_eq!(ctx.additions.load(Ordering::SeqCst), 1); - ctx.additions.store(0, Ordering::SeqCst); - - leaf.incr(&ctx); - // This should be less the 20 to prove that we are reusing trees - assert_eq!(ctx.additions.load(Ordering::SeqCst), 9); - ctx.additions.store(0, Ordering::SeqCst); - - { - let root_info = leaf.inner.lock().aggregation_leaf.get_root_info(&ctx, &()); - assert!(root_info); - } -} - -#[test] -fn chain_double_connected() { - let something_with_lifetime = 0; - let ctx = NodeAggregationContext { - additions: AtomicU32::new(0), - something_with_lifetime: &something_with_lifetime, - add_value: true, - }; - let leaf = Arc::new(Node { - inner: Mutex::new(NodeInner { - children: vec![], - aggregation_leaf: AggregationTreeLeaf::new(), - value: 1, - }), - }); - let mut current = leaf.clone(); - let mut current2 = Arc::new(Node { - inner: Mutex::new(NodeInner { - children: vec![leaf.clone()], - aggregation_leaf: AggregationTreeLeaf::new(), - value: 2, - }), - }); - for i in 3..=100 { - let new_node = Arc::new(Node { - inner: Mutex::new(NodeInner { - children: vec![current, current2.clone()], - aggregation_leaf: AggregationTreeLeaf::new(), - value: i, - }), - }); - current = current2; - current2 = new_node; - } - let current = NodeRef(current2); - - print(&ctx, ¤t); - - { - let aggregated = aggregation_info(&ctx, ¤t); - assert_eq!(aggregated.lock().value, 8230); - } - assert_eq!(ctx.additions.load(Ordering::SeqCst), 204); - ctx.additions.store(0, Ordering::SeqCst); -} - -const RECT_SIZE: usize = 100; -const RECT_MULT: usize = 100; - -#[test] -fn rectangle_tree() { - let something_with_lifetime = 0; - let ctx = NodeAggregationContext { - additions: AtomicU32::new(0), - something_with_lifetime: &something_with_lifetime, - add_value: false, - }; - let mut nodes: Vec>> = Vec::new(); - for y in 0..RECT_SIZE { - let mut line: Vec> = Vec::new(); - for x in 0..RECT_SIZE { - let mut children = Vec::new(); - if x > 0 { - children.push(line[x - 1].clone()); - } - if y > 0 { - children.push(nodes[y - 1][x].clone()); - } - let value = (x + y * RECT_MULT) as u32; - let node = Arc::new(Node { - inner: Mutex::new(NodeInner { - children, - aggregation_leaf: AggregationTreeLeaf::new(), - value, - }), - }); - line.push(node.clone()); - } - nodes.push(line); - } - - let root = NodeRef(nodes[RECT_SIZE - 1][RECT_SIZE - 1].clone()); - - print(&ctx, &root); -} - -#[test] -fn rectangle_adding_tree() { - let something_with_lifetime = 0; - let ctx = NodeAggregationContext { - additions: AtomicU32::new(0), - something_with_lifetime: &something_with_lifetime, - add_value: false, - }; - let mut nodes: Vec>> = Vec::new(); - - fn add_child( - parent: &Arc, - node: &Arc, - aggregation_context: &NodeAggregationContext<'_>, - ) { - let node_ref = NodeRef(node.clone()); - let mut state = parent.inner.lock(); - state.children.push(node.clone()); - let job = state - .aggregation_leaf - .add_child_job(aggregation_context, &node_ref); - drop(state); - job(); - } - for y in 0..RECT_SIZE { - let mut line: Vec> = Vec::new(); - for x in 0..RECT_SIZE { - let value = (x + y * RECT_MULT) as u32; - let node = Arc::new(Node { - inner: Mutex::new(NodeInner { - children: Vec::new(), - aggregation_leaf: AggregationTreeLeaf::new(), - value, - }), - }); - line.push(node.clone()); - if x > 0 { - let parent = &line[x - 1]; - add_child(parent, &node, &ctx); - } - if y > 0 { - let parent = &nodes[y - 1][x]; - add_child(parent, &node, &ctx); - } - if x == 0 && y == 0 { - aggregation_info(&ctx, &NodeRef(node.clone())).lock().active = true; - } - } - nodes.push(line); - } - - let root = NodeRef(nodes[0][0].clone()); - - print(&ctx, &root); -} - -#[test] -fn many_children() { - let something_with_lifetime = 0; - let ctx = NodeAggregationContext { - additions: AtomicU32::new(0), - something_with_lifetime: &something_with_lifetime, - add_value: false, - }; - let mut roots: Vec> = Vec::new(); - let mut children: Vec> = Vec::new(); - const CHILDREN: u32 = 5000; - const ROOTS: u32 = 100; - let inner_node = Arc::new(Node { - inner: Mutex::new(NodeInner { - children: Vec::new(), - aggregation_leaf: AggregationTreeLeaf::new(), - value: 0, - }), - }); - let start = Instant::now(); - for i in 0..ROOTS { - let node = Arc::new(Node { - inner: Mutex::new(NodeInner { - children: Vec::new(), - aggregation_leaf: AggregationTreeLeaf::new(), - value: 10000 + i, - }), - }); - roots.push(node.clone()); - aggregation_info(&ctx, &NodeRef(node.clone())).lock().active = true; - connect_child(&ctx, &node, &inner_node); - } - println!("Roots: {:?}", start.elapsed()); - let start = Instant::now(); - for i in 0..CHILDREN { - let node = Arc::new(Node { - inner: Mutex::new(NodeInner { - children: Vec::new(), - aggregation_leaf: AggregationTreeLeaf::new(), - value: 20000 + i, - }), - }); - children.push(node.clone()); - connect_child(&ctx, &inner_node, &node); - } - println!("Children: {:?}", start.elapsed()); - let start = Instant::now(); - for i in 0..ROOTS { - let node = Arc::new(Node { - inner: Mutex::new(NodeInner { - children: Vec::new(), - aggregation_leaf: AggregationTreeLeaf::new(), - value: 30000 + i, - }), - }); - roots.push(node.clone()); - aggregation_info(&ctx, &NodeRef(node.clone())).lock().active = true; - connect_child(&ctx, &node, &inner_node); - } - println!("Roots: {:?}", start.elapsed()); - let start = Instant::now(); - for i in 0..CHILDREN { - let node = Arc::new(Node { - inner: Mutex::new(NodeInner { - children: Vec::new(), - aggregation_leaf: AggregationTreeLeaf::new(), - value: 40000 + i, - }), - }); - children.push(node.clone()); - connect_child(&ctx, &inner_node, &node); - } - let children_duration = start.elapsed(); - println!("Children: {:?}", children_duration); - let mut number_of_slow_children = 0; - for _ in 0..10 { - let start = Instant::now(); - for i in 0..CHILDREN { - let node = Arc::new(Node { - inner: Mutex::new(NodeInner { - children: Vec::new(), - aggregation_leaf: AggregationTreeLeaf::new(), - value: 40000 + i, - }), - }); - children.push(node.clone()); - connect_child(&ctx, &inner_node, &node); - } - let dur = start.elapsed(); - println!("Children: {:?}", dur); - if dur > children_duration * 2 { - number_of_slow_children += 1; - } - } - - // Technically it should always be 0, but the performance of the environment - // might vary so we accept a few slow children - assert!(number_of_slow_children < 3); - - let root = NodeRef(roots[0].clone()); - - print(&ctx, &root); -} - -fn connect_child( - aggregation_context: &NodeAggregationContext<'_>, - parent: &Arc, - child: &Arc, -) { - let state = parent.inner.lock(); - let node_ref = NodeRef(child.clone()); - let mut node_guard = unsafe { NodeGuard::new(state, parent.clone()) }; - while let Some(job) = ensure_thresholds(aggregation_context, &mut node_guard) { - drop(node_guard); - job(); - node_guard = unsafe { NodeGuard::new(parent.inner.lock(), parent.clone()) }; - } - let NodeGuard { - guard: mut state, .. - } = node_guard; - state.children.push(child.clone()); - let job = state - .aggregation_leaf - .add_child_job(aggregation_context, &node_ref); - drop(state); - job(); -} - -fn print(aggregation_context: &NodeAggregationContext<'_>, current: &NodeRef) { - println!("digraph {{"); - let start = 0; - let end = 3; - for i in start..end { - print_graph(aggregation_context, current, i, false, |item| { - format!("{}", item.0.inner.lock().value) - }); - } - for i in start + 1..end + 1 { - print_graph(aggregation_context, current, i, true, |item| { - format!("{}", item.0.inner.lock().value) - }); - } - println!("\n}}"); -} diff --git a/crates/turbo-tasks-memory/src/aggregation_tree/top_tree.rs b/crates/turbo-tasks-memory/src/aggregation_tree/top_tree.rs deleted file mode 100644 index da21c55d4d4c4..0000000000000 --- a/crates/turbo-tasks-memory/src/aggregation_tree/top_tree.rs +++ /dev/null @@ -1,180 +0,0 @@ -use std::{mem::transmute, ops::ControlFlow, sync::Arc}; - -use parking_lot::{Mutex, MutexGuard}; -use ref_cast::RefCast; - -use super::{inner_refs::TopRef, leaf::top_tree, AggregationContext}; -use crate::count_hash_set::CountHashSet; - -/// The top half of the aggregation tree. It can aggregate all nodes of a -/// subgraph. To do that it used a [BottomTree] of a specific height and, since -/// a bottom tree only aggregates up to a specific connectivity, also another -/// TopTree of the current depth + 1. This continues recursively until all nodes -/// are aggregated. -pub struct TopTree { - pub depth: u8, - state: Mutex>, -} - -struct TopTreeState { - data: T, - upper: CountHashSet>, -} - -impl TopTree { - pub fn new(depth: u8) -> Self { - Self { - depth, - state: Mutex::new(TopTreeState { - data: T::default(), - upper: CountHashSet::new(), - }), - } - } -} - -impl TopTree { - pub fn add_children_of_child<'a, C: AggregationContext>( - self: &Arc, - aggregation_context: &C, - children: impl IntoIterator, - ) where - C::ItemRef: 'a, - { - for child in children { - top_tree(aggregation_context, child, self.depth + 1) - .add_upper(aggregation_context, self); - } - } - - pub fn add_child_of_child>( - self: &Arc, - aggregation_context: &C, - child_of_child: &C::ItemRef, - ) { - top_tree(aggregation_context, child_of_child, self.depth + 1) - .add_upper(aggregation_context, self); - } - - pub fn remove_child_of_child>( - self: &Arc, - aggregation_context: &C, - child_of_child: &C::ItemRef, - ) { - top_tree(aggregation_context, child_of_child, self.depth + 1) - .remove_upper(aggregation_context, self); - } - - pub fn remove_children_of_child<'a, C: AggregationContext>( - self: &Arc, - aggregation_context: &C, - children: impl IntoIterator, - ) where - C::ItemRef: 'a, - { - for child in children { - top_tree(aggregation_context, child, self.depth + 1) - .remove_upper(aggregation_context, self); - } - } - - pub fn add_upper>( - &self, - aggregation_context: &C, - upper: &Arc>, - ) { - let mut state = self.state.lock(); - if state.upper.add_clonable(TopRef::ref_cast(upper)) { - if let Some(change) = aggregation_context.info_to_add_change(&state.data) { - upper.child_change(aggregation_context, &change); - } - } - } - - pub fn remove_upper>( - &self, - aggregation_context: &C, - upper: &Arc>, - ) { - let mut state = self.state.lock(); - if state.upper.remove_clonable(TopRef::ref_cast(upper)) { - if let Some(change) = aggregation_context.info_to_remove_change(&state.data) { - upper.child_change(aggregation_context, &change); - } - } - } - - pub fn child_change>( - &self, - aggregation_context: &C, - change: &C::ItemChange, - ) { - let mut state = self.state.lock(); - let change = aggregation_context.apply_change(&mut state.data, change); - propagate_change_to_upper(&state, aggregation_context, change); - } - - pub fn get_root_info>( - &self, - aggregation_context: &C, - root_info_type: &C::RootInfoType, - ) -> C::RootInfo { - let state = self.state.lock(); - if self.depth == 0 { - // This is the root - aggregation_context.info_to_root_info(&state.data, root_info_type) - } else { - let mut result = aggregation_context.new_root_info(root_info_type); - for TopRef { upper } in state.upper.iter() { - let info = upper.get_root_info(aggregation_context, root_info_type); - if aggregation_context.merge_root_info(&mut result, info) == ControlFlow::Break(()) - { - break; - } - } - result - } - } - - pub fn lock_info(self: &Arc) -> AggregationInfoGuard { - AggregationInfoGuard { - // SAFETY: We can cast the lifetime as we keep a strong reference to the tree. - // The order of the field in the struct is important to drop guard before tree. - guard: unsafe { transmute(self.state.lock()) }, - tree: self.clone(), - } - } -} - -fn propagate_change_to_upper( - state: &MutexGuard>, - aggregation_context: &C, - change: Option, -) { - let Some(change) = change else { - return; - }; - for TopRef { upper } in state.upper.iter() { - upper.child_change(aggregation_context, &change); - } -} - -pub struct AggregationInfoGuard { - guard: MutexGuard<'static, TopTreeState>, - #[allow(dead_code, reason = "need to stay alive until the guard is dropped")] - tree: Arc>, -} - -impl std::ops::Deref for AggregationInfoGuard { - type Target = T; - - fn deref(&self) -> &Self::Target { - &self.guard.data - } -} - -impl std::ops::DerefMut for AggregationInfoGuard { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.guard.data - } -} diff --git a/crates/turbo-tasks-memory/src/cell.rs b/crates/turbo-tasks-memory/src/cell.rs index d006bebd1ead6..d2b8998d25fb8 100644 --- a/crates/turbo-tasks-memory/src/cell.rs +++ b/crates/turbo-tasks-memory/src/cell.rs @@ -75,41 +75,6 @@ impl Cell { } } - /// Returns true if the cell has dependent tasks. - pub fn has_dependent_tasks(&self) -> bool { - match self { - Cell::Empty => false, - Cell::Recomputing { - dependent_tasks, .. - } - | Cell::Value { - dependent_tasks, .. - } - | Cell::TrackedValueless { - dependent_tasks, .. - } => !dependent_tasks.is_empty(), - } - } - - /// Returns the list of dependent tasks. - pub fn dependent_tasks(&self) -> &TaskIdSet { - match self { - Cell::Empty => { - static EMPTY: TaskIdSet = AutoSet::with_hasher(); - &EMPTY - } - Cell::Value { - dependent_tasks, .. - } - | Cell::TrackedValueless { - dependent_tasks, .. - } - | Cell::Recomputing { - dependent_tasks, .. - } => dependent_tasks, - } - } - /// Switch the cell to recomputing state. fn recompute( &mut self, @@ -235,6 +200,9 @@ impl Cell { } => { // Assigning to a cell will invalidate all dependent tasks as the content might // have changed. + // TODO this leads to flagging task unnecessarily dirty when a GC'ed task is + // recomputed. We need to use the notification of changed cells for the current + // task to check if it's valid to skip the invalidation here if !dependent_tasks.is_empty() { turbo_tasks.schedule_notify_tasks_set(dependent_tasks); } diff --git a/crates/turbo-tasks-memory/src/concurrent_priority_queue.rs b/crates/turbo-tasks-memory/src/concurrent_priority_queue.rs deleted file mode 100644 index 53c193072db0b..0000000000000 --- a/crates/turbo-tasks-memory/src/concurrent_priority_queue.rs +++ /dev/null @@ -1,185 +0,0 @@ -use std::{ - cmp::min, - collections::{hash_map::RandomState, BinaryHeap}, - fmt::Debug, - hash::{BuildHasher, Hash}, -}; - -use once_cell::sync::OnceCell; -use parking_lot::{Mutex, MutexGuard}; -use priority_queue::PriorityQueue; - -// shard_amount and shift are stolen from the dashmap crate implementation: -// https://github.com/xacrimon/dashmap/blob/0b2a2269b2d368494eeb41d4218da1b142da8e77/src/lib.rs#L64-L69 -// They are changed to use use 4 times the number of shards, since inserting -// into a priority queue is more expensive than a hashmap. So creating more -// shards will reduce contention. - -// Returns the number of shards to use. -fn shard_amount() -> usize { - static SHARD_AMOUNT: OnceCell = OnceCell::new(); - *SHARD_AMOUNT.get_or_init(|| { - (std::thread::available_parallelism().map_or(1, usize::from) * 16).next_power_of_two() - }) -} - -/// Returns the number of bits to shift a hash to get the shard index. -fn shift() -> usize { - static SHIFT: OnceCell = OnceCell::new(); - *SHIFT - .get_or_init(|| std::mem::size_of::() * 8 - shard_amount().trailing_zeros() as usize) -} - -pub struct ConcurrentPriorityQueue { - shards: Box<[Mutex>]>, - hasher: H, -} - -impl - ConcurrentPriorityQueue -{ - pub fn new() -> Self { - Self::with_hasher(Default::default()) - } -} - -impl - ConcurrentPriorityQueue -{ - pub fn with_hasher(hasher: H) -> Self { - let shards = (0..shard_amount()) - .map(|_| Mutex::new(PriorityQueue::with_hasher(hasher.clone()))) - .collect::>(); - Self { - shards: shards.into_boxed_slice(), - hasher, - } - } - - fn shard(&self, key: &K) -> MutexGuard> { - // Leave the high 7 bits for the HashBrown SIMD tag. - // see https://github.com/xacrimon/dashmap/blob/0b2a2269b2d368494eeb41d4218da1b142da8e77/src/lib.rs#L374 - let index = ((self.hasher.hash_one(key) as usize) << 7) >> shift(); - unsafe { self.shards.get_unchecked(index) }.lock() - } - - #[allow(dead_code)] - pub fn len(&self) -> usize { - let mut len = 0; - for shard in self.shards.iter() { - len += shard.lock().len() - } - len - } - - pub fn insert(&self, key: K, value: V) { - let mut inner = self.shard(&key); - inner.push(key, value); - } - - pub fn upsert_with( - &self, - key: K, - default_value: impl FnOnce() -> V, - value_update: impl FnOnce(&mut V), - ) { - let mut inner = self.shard(&key); - if !inner.change_priority_by(&key, value_update) { - inner.push(key, default_value()); - } - } - - /// Pops at most `min(factor / 256 * len, max_count)` items from the queue. - /// Due to concurrency, the actual amount of items may vary. The - /// returned vector is in any order, if you want items to be ordered you - /// need to sort it. - pub fn pop_factor(&self, factor: u8, max_count: usize) -> Vec<(K, V)> { - struct ShardsQueueItem { - index: usize, - value: V, - len: usize, - } - impl Ord for ShardsQueueItem { - fn cmp(&self, other: &Self) -> std::cmp::Ordering { - self.value - .cmp(&other.value) - // In case of equal priority we want to select the shard with the - // largest number of items, so we balance the load on shards. - .then_with(|| self.len.cmp(&other.len)) - } - } - impl PartialOrd for ShardsQueueItem { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } - } - impl PartialEq for ShardsQueueItem { - fn eq(&self, _other: &Self) -> bool { - unreachable!() - } - } - impl Eq for ShardsQueueItem {} - - // We build a priority queue of the shards so we can select from the shards in - // correct order. But this is only a snapshot of the shards, so any - // concurrent change to the shard will not be respected, but we are fine with - // that. - let mut shards_queue = BinaryHeap::with_capacity(self.shards.len()); - let mut total_len = 0; - for (i, shard) in self.shards.iter().enumerate() { - let shard = shard.lock(); - let len = shard.len(); - total_len += len; - if let Some((_, v)) = shard.peek() { - shards_queue.push(ShardsQueueItem { - index: i, - value: v.clone(), - len, - }); - } - } - let count = min(factor as usize * total_len / u8::MAX as usize, max_count); - let mut result = Vec::with_capacity(count); - loop { - if let Some(ShardsQueueItem { index: i, .. }) = shards_queue.pop() { - let mut shard = unsafe { self.shards.get_unchecked(i) }.lock(); - if let Some(ShardsQueueItem { - value: next_value, .. - }) = shards_queue.peek() - { - // The peek will be None if the shard has become empty concurrently - while let Some((_, peeked_value)) = shard.peek() { - // Is the next item in this shard (still) the global next - if peeked_value < next_value { - // some other shard is next - // enqueue this shard again - shards_queue.push(ShardsQueueItem { - index: i, - value: peeked_value.clone(), - len: shard.len(), - }); - break; - } - - result.push(shard.pop().unwrap()); - if result.len() >= count { - return result; - } - // We keep the shard lock and check the next item for a - // fast path - } - } else { - // No other shards - for _ in result.len()..count { - if let Some(item) = shard.pop() { - result.push(item); - } else { - break; - } - } - return result; - } - } - } - } -} diff --git a/crates/turbo-tasks-memory/src/count_hash_set.rs b/crates/turbo-tasks-memory/src/count_hash_set.rs index 5e72c31d43524..b118a4c3c0f00 100644 --- a/crates/turbo-tasks-memory/src/count_hash_set.rs +++ b/crates/turbo-tasks-memory/src/count_hash_set.rs @@ -1,5 +1,6 @@ use std::{ borrow::Borrow, + cmp::Ordering, collections::hash_map::RandomState, fmt::{Debug, Formatter}, hash::{BuildHasher, Hash}, @@ -45,6 +46,16 @@ impl Default for CountHashSet { } } +impl FromIterator for CountHashSet { + fn from_iter>(iter: I) -> Self { + let mut set = CountHashSet::default(); + for item in iter { + set.add(item); + } + set + } +} + impl CountHashSet { pub fn new() -> Self { Self::default() @@ -71,6 +82,12 @@ pub enum RemoveIfEntryResult { NotPresent, } +pub struct RemovePositiveCountResult { + pub removed: bool, + pub removed_count: usize, + pub count: isize, +} + impl CountHashSet { /// Returns true, when the value has become visible from outside pub fn add_count(&mut self, item: T, count: usize) -> bool { @@ -135,41 +152,6 @@ impl CountHashSet { } } - /// Returns true when the value is no longer visible from outside - pub fn remove_count(&mut self, item: T, count: usize) -> bool { - if count == 0 { - return false; - } - match self.inner.entry(item) { - Entry::Occupied(mut e) => { - let value = e.get_mut(); - let old = *value; - *value -= count as isize; - if *value > 0 { - // It was and still is positive - false - } else if *value == 0 { - // It was positive and has become zero - e.remove(); - true - } else if old > 0 { - // It was positive and is negative now - self.negative_entries += 1; - true - } else { - // It was and still is negative - false - } - } - Entry::Vacant(e) => { - // It was zero and is negative now - e.insert(-(count as isize)); - self.negative_entries += 1; - false - } - } - } - /// Removes an item if it is present. pub fn remove_if_entry(&mut self, item: &T) -> RemoveIfEntryResult { match self.inner.raw_entry_mut(item) { @@ -197,6 +179,13 @@ impl CountHashSet { count: self.inner.len() - self.negative_entries, } } + + pub fn get_count(&self, item: &T) -> isize { + match self.inner.get(item) { + Some(value) => *value, + None => 0, + } + } } impl CountHashSet { @@ -275,9 +264,71 @@ impl CountHashSet { } } - /// Returns true, when the value is no longer visible from outside - pub fn remove_clonable(&mut self, item: &T) -> bool { - self.remove_clonable_count(item, 1) + /// Returns true when the value is no longer visible from outside + pub fn remove_positive_clonable_count( + &mut self, + item: &T, + count: usize, + ) -> RemovePositiveCountResult { + if count == 0 { + return RemovePositiveCountResult { + removed: false, + removed_count: 0, + count: self.inner.get(item).copied().unwrap_or(0), + }; + } + match self.inner.raw_entry_mut(item) { + RawEntry::Occupied(mut e) => { + let value = e.get_mut(); + let old = *value; + match old.cmp(&(count as isize)) { + Ordering::Less => { + if old < 0 { + // It's already negative, can't remove anything + RemovePositiveCountResult { + removed: false, + removed_count: 0, + count: old, + } + } else { + // It's removed completely with count remaining + e.remove(); + RemovePositiveCountResult { + removed: true, + removed_count: old as usize, + count: 0, + } + } + } + Ordering::Equal => { + // It's perfectly removed + e.remove(); + RemovePositiveCountResult { + removed: true, + removed_count: count, + count: 0, + } + } + Ordering::Greater => { + // It's partially removed + *value -= count as isize; + RemovePositiveCountResult { + removed: false, + removed_count: count, + count: *value, + } + } + } + } + RawEntry::Vacant(_) => { + // It's not present + RemovePositiveCountResult { + removed: false, + removed_count: 0, + count: 0, + } + } + } } } @@ -334,19 +385,19 @@ mod tests { assert_eq!(set.len(), 2); assert!(!set.is_empty()); - assert!(set.remove_count(2, 2)); + assert!(set.remove_clonable_count(&2, 2)); assert_eq!(set.len(), 1); assert!(!set.is_empty()); - assert!(!set.remove_count(2, 1)); + assert!(!set.remove_clonable_count(&2, 1)); assert_eq!(set.len(), 1); assert!(!set.is_empty()); - assert!(!set.remove_count(1, 1)); + assert!(!set.remove_clonable_count(&1, 1)); assert_eq!(set.len(), 1); assert!(!set.is_empty()); - assert!(set.remove_count(1, 1)); + assert!(set.remove_clonable_count(&1, 1)); assert_eq!(set.len(), 0); assert!(set.is_empty()); @@ -366,15 +417,15 @@ mod tests { assert_eq!(set.len(), 0); assert!(set.is_empty()); - assert!(set.add_clonable(&1)); + assert!(set.add_clonable_count(&1, 1)); assert_eq!(set.len(), 1); assert!(!set.is_empty()); - assert!(!set.add_clonable(&1)); + assert!(!set.add_clonable_count(&1, 1)); assert_eq!(set.len(), 1); assert!(!set.is_empty()); - assert!(set.add_clonable(&2)); + assert!(set.add_clonable_count(&2, 1)); assert_eq!(set.len(), 2); assert!(!set.is_empty()); @@ -442,7 +493,7 @@ mod tests { assert_eq!(set.len(), 0); assert!(set.is_empty()); - assert!(!set.remove_count(1, 0)); + assert!(!set.remove_clonable_count(&1, 0)); assert_eq!(set.len(), 0); assert!(set.is_empty()); @@ -454,7 +505,7 @@ mod tests { assert_eq!(set.len(), 0); assert!(set.is_empty()); - assert!(!set.remove_count(1, 1)); + assert!(!set.remove_clonable_count(&1, 1)); assert_eq!(set.len(), 0); assert!(set.is_empty()); diff --git a/crates/turbo-tasks-memory/src/gc.rs b/crates/turbo-tasks-memory/src/gc.rs index c3f117346e7ce..b0253fa0e8110 100644 --- a/crates/turbo-tasks-memory/src/gc.rs +++ b/crates/turbo-tasks-memory/src/gc.rs @@ -1,224 +1,269 @@ use std::{ - cmp::Reverse, - collections::HashMap, - time::{Duration, Instant}, + cmp::{max, Reverse}, + collections::VecDeque, + fmt::Debug, + mem::take, + sync::atomic::{AtomicU32, AtomicUsize, Ordering}, + time::Duration, }; use concurrent_queue::ConcurrentQueue; -use nohash_hasher::BuildNoHashHasher; -use turbo_tasks::{small_duration::SmallDuration, TaskId, TurboTasksBackendApi}; +use parking_lot::Mutex; +use tracing::field::{debug, Empty}; +use turbo_tasks::TaskId; -use crate::{concurrent_priority_queue::ConcurrentPriorityQueue, MemoryBackend}; +use crate::MemoryBackend; /// The priority of a task for garbage collection. /// Any action will shrink the internal memory structures of the task in a /// transparent way. -#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Copy, Clone)] -pub enum GcPriority { - // The order influences priority. Put the highest priority first. - /// Unload cells that are currently not read by any task. This might cause - /// the task to recompute when these cells are read. - InactiveEmptyUnusedCells { - compute_duration: SmallDuration<10_000>, - }, - /// Unload the whole task. Only available for inactive tasks. - InactiveUnload { - /// The age of the task. Stored as 2^x seconds to - /// bucket tasks and avoid frequent revalidation. - age: Reverse, - /// Aggregated recompute time. Stored as 2^x milliseconds to bucket - /// tasks and avoid frequent revalidation. - total_compute_duration: u8, - }, - /// Unload cells that are currently not read by any task. This might cause - /// the task to recompute when these cells are read. - EmptyUnusedCells { - compute_duration: SmallDuration<10_000>, - }, - /// Unload all cells, and continue tracking them valueless. This might cause - /// the task and dependent tasks to recompute when these cells are read. - EmptyCells { - /// Aggregated recompute time. Stored as 2^x milliseconds to bucket - /// tasks and avoid frequent revalidation. - total_compute_duration: u8, - /// The age of the task. Stored as 2^x seconds to - /// bucket tasks and avoid frequent revalidation. - age: Reverse, - }, - Placeholder, -} - -/// Statistics about actions performed during garbage collection. -#[derive(Default, Debug)] -pub struct GcStats { - /// How many tasks were unloaded. - pub unloaded: usize, - /// How many unused cells were emptied. - pub empty_unused: usize, - /// How many unused cells were emptied (on the fast path). - pub empty_unused_fast: usize, - /// How many used cells were emptied. - pub empty_cells: usize, - /// How often the priority of a task was updated. - pub priority_updated: usize, - /// How often the priority of a task was updated (on the fast path). - pub priority_updated_fast: usize, - /// How many tasks were checked but did not need to have any action taken. - pub no_gc_needed: usize, - /// How many tasks were checked but were in a state where no action could be - /// taken. - pub no_gc_possible: usize, +#[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord, Copy, Clone)] +pub struct GcPriority { + // Memory usage divided by compute duration. Specifies how efficient garbage collection would + // be with this task. Higher memory usage and lower compute duration makes it more likely to be + // garbage collected. + memory_per_time: u16, } /// State about garbage collection for a task. -#[derive(Debug, Default)] +#[derive(Clone, Copy, Debug, Default)] pub struct GcTaskState { - pub inactive: bool, + pub priority: GcPriority, + /// The generation where the task was last accessed. + pub generation: u32, +} + +impl GcTaskState { + pub(crate) fn execution_completed( + &mut self, + duration: Duration, + memory_usage: usize, + generation: u32, + ) { + self.generation = generation; + self.priority = GcPriority { + memory_per_time: ((memory_usage + TASK_BASE_MEMORY_USAGE) as u64 + / (duration.as_micros() as u64 + TASK_BASE_COMPUTE_DURATION_IN_MICROS)) + .try_into() + .unwrap_or(u16::MAX), + }; + } + + pub(crate) fn on_read(&mut self, generation: u32) -> bool { + if self.generation < generation { + self.generation = generation; + true + } else { + false + } + } +} + +const TASKS_PER_NEW_GENERATION: usize = 100_000; +const MAX_TASKS_PER_OLD_GENERATION: usize = 200_000; +const PERCENTAGE_TO_COLLECT: usize = 30; +const TASK_BASE_MEMORY_USAGE: usize = 1_000; +const TASK_BASE_COMPUTE_DURATION_IN_MICROS: u64 = 1_000; +pub const PERCENTAGE_TARGET_MEMORY: usize = 88; +pub const PERCENTAGE_IDLE_TARGET_MEMORY: usize = 75; + +struct OldGeneration { + tasks: Vec, + generation: u32, +} + +struct ProcessGenerationResult { + priority: Option, + count: usize, } /// The queue of actions that garbage collection should perform. pub struct GcQueue { - /// Tasks that should be checked for inactive propagation. - inactive_propagate_queue: ConcurrentQueue, - /// Tasks ordered by gc priority. - queue: ConcurrentPriorityQueue>, + /// The current generation number. + generation: AtomicU32, + /// Fresh or read tasks that should added to the queue. + incoming_tasks: ConcurrentQueue, + /// Number of tasks in `incoming_tasks`. + incoming_tasks_count: AtomicUsize, + /// Tasks from old generations. The oldest generation will be garbage + /// collected next. + generations: Mutex>, } impl GcQueue { pub fn new() -> Self { Self { - inactive_propagate_queue: ConcurrentQueue::unbounded(), - queue: ConcurrentPriorityQueue::new(), + generation: AtomicU32::new(0), + incoming_tasks: ConcurrentQueue::unbounded(), + incoming_tasks_count: AtomicUsize::new(0), + generations: Mutex::new(VecDeque::with_capacity(128)), } } + /// Get the current generation number. + pub fn generation(&self) -> u32 { + self.generation.load(Ordering::Relaxed) + } + /// Notify the GC queue that a task has been executed. - pub fn task_executed(&self, task: TaskId, duration: Duration) { - // A freshly executed task will start on EmptyUnusedCells, even while we are not - // sure if there are unused cells. - let compute_duration = duration.into(); - let value = Reverse(GcPriority::EmptyUnusedCells { compute_duration }); - self.queue.insert(task, value); + pub fn task_executed(&self, task: TaskId) -> u32 { + self.add_task(task) } - /// Notify the GC queue that a task might become inactive. - pub fn task_might_become_inactive(&self, task: TaskId) { - let _ = self.inactive_propagate_queue.push(task); + /// Notify the GC queue that a task has been accessed. + pub fn task_accessed(&self, task: TaskId) -> u32 { + self.add_task(task) } - /// Notify the GC queue that a task has become inactive. This means the - /// [GcTaskState]::inactive has been set. - pub fn task_flagged_inactive(&self, task: TaskId, compute_duration: Duration) { - self.queue.upsert_with( - task, - || { - // When there is no entry, we schedule the minimum priority. - Reverse(GcPriority::InactiveEmptyUnusedCells { - compute_duration: compute_duration.into(), - }) - }, - |value| { - match &mut value.0 { - GcPriority::InactiveEmptyUnusedCells { .. } - | GcPriority::InactiveUnload { .. } => { - // already inactive + fn add_task(&self, task: TaskId) -> u32 { + let _ = self.incoming_tasks.push(task); + if self.incoming_tasks_count.fetch_add(1, Ordering::Acquire) % TASKS_PER_NEW_GENERATION + == TASKS_PER_NEW_GENERATION - 1 + { + self.incoming_tasks_count + .fetch_sub(TASKS_PER_NEW_GENERATION, Ordering::Release); + // We are selected to move TASKS_PER_NEW_GENERATION tasks into a generation + let gen = self.generation.fetch_add(1, Ordering::Relaxed); + let mut tasks = Vec::with_capacity(TASKS_PER_NEW_GENERATION); + for _ in 0..TASKS_PER_NEW_GENERATION { + match self.incoming_tasks.pop() { + Ok(task) => { + tasks.push(task); } - GcPriority::EmptyUnusedCells { compute_duration } => { - // Convert to the higher priority inactive version. - *value = Reverse(GcPriority::InactiveEmptyUnusedCells { - compute_duration: *compute_duration, - }) + Err(_) => { + // That will not happen, since we only pop the same amount as we have + // pushed. + unreachable!(); } - GcPriority::EmptyCells { - age, - total_compute_duration, - } => { - // Convert to the higher priority inactive version. - *value = Reverse(GcPriority::InactiveUnload { - age: *age, - total_compute_duration: *total_compute_duration, - }) - } - GcPriority::Placeholder => unreachable!(), } - }, - ); + } + self.generations.lock().push_front(OldGeneration { + tasks, + generation: gen, + }); + gen + } else { + self.generation.load(Ordering::Relaxed) + } } - /// Run garbage collection on the queue. The `factor` parameter controls how - /// much work should be done. It's a value between 0 and 255, where 255 - /// performs all the work possible. - pub fn run_gc( - &self, - factor: u8, - backend: &MemoryBackend, - turbo_tasks: &dyn TurboTasksBackendApi, - ) -> Option<(GcPriority, usize, GcStats)> { - // Process through the inactive propagation queue. - while let Ok(task) = self.inactive_propagate_queue.pop() { - backend.with_task(task, |task| { - task.gc_check_inactive(backend); + fn process_old_generation(&self, backend: &MemoryBackend) -> ProcessGenerationResult { + let old_generation = { + let guard = &mut self.generations.lock(); + guard.pop_back() + }; + let Some(OldGeneration { + mut tasks, + generation, + }) = old_generation + else { + // No old generation to process + return ProcessGenerationResult { + priority: None, + count: 0, + }; + }; + // Check all tasks for the correct generation + let mut indices = Vec::with_capacity(tasks.len()); + assert!(tasks.len() <= MAX_TASKS_PER_OLD_GENERATION); + for (i, task) in tasks.iter().enumerate() { + backend.with_task(*task, |task| { + if let Some(state) = task.gc_state() { + if state.generation <= generation { + indices.push((Reverse(state.priority), i as u32)); + } + } }); } - if factor == 0 { - return None; + if indices.is_empty() { + // No valid tasks in old generation to process + return ProcessGenerationResult { + priority: None, + count: 0, + }; } - // Process through the gc queue. - let now = turbo_tasks.program_duration_until(Instant::now()); - let mut task_duration_cache = HashMap::with_hasher(BuildNoHashHasher::default()); - let mut stats = GcStats::default(); - let result = self.select_tasks(factor, |task_id, _priority, max_priority| { - backend.with_task(task_id, |task| { - task.run_gc( - now, - max_priority, - &mut task_duration_cache, - &mut stats, - backend, - turbo_tasks, - ) - }) - }); - result.map(|(p, c)| (p, c, stats)) - } - - /// Select a number of tasks to run garbage collection on and run the - /// `execute` function on them. - pub fn select_tasks( - &self, - factor: u8, - mut execute: impl FnMut(TaskId, GcPriority, GcPriority) -> Option, - ) -> Option<(GcPriority, usize)> { - const MAX_POP: usize = 1000000; - let jobs = self.queue.pop_factor(factor, MAX_POP); - if jobs.is_empty() { - return None; + // Sorting based on sort_by_cached_key from std lib + indices.sort_unstable(); + for i in 0..indices.len() { + let mut index = indices[i].1; + while (index as usize) < i { + index = indices[index as usize].1; + } + indices[i].1 = index; + tasks.swap(i, index as usize); } - let highest_priority = jobs.iter().map(|&(_, Reverse(p))| p).max().unwrap(); - let len = jobs.len(); - for (task, Reverse(priority)) in jobs { - if let Some(new_priority) = execute(task, priority, highest_priority) { - self.queue.upsert_with( - task, - || Reverse(new_priority), - |value| { - if *value < Reverse(new_priority) { - *value = Reverse(new_priority); + tasks.truncate(indices.len()); + + let tasks_to_collect = max(1, tasks.len() * PERCENTAGE_TO_COLLECT / 100); + let (Reverse(max_priority), _) = indices[0]; + drop(indices); + + // Put back remaining tasks into the queue + let remaining_tasks = &tasks[tasks_to_collect..]; + { + let mut guard = self.generations.lock(); + if !remaining_tasks.is_empty() { + if let Some(first) = guard.front_mut() { + first.tasks.extend(remaining_tasks); + if first.tasks.len() > MAX_TASKS_PER_OLD_GENERATION { + // Need to split the tasks into two generations + let mut gen_b = Vec::with_capacity(first.tasks.len() / 2); + let mut gen_a = Vec::with_capacity(first.tasks.len() - gen_b.capacity()); + for (i, task) in take(&mut first.tasks).into_iter().enumerate() { + if i % 2 == 0 { + gen_a.push(task); + } else { + gen_b.push(task); + } } - }, - ); + let generation = first.generation; + first.tasks = gen_a; + guard.push_front(OldGeneration { + tasks: gen_b, + generation, + }); + } + } else { + guard.push_front(OldGeneration { + tasks: remaining_tasks.to_vec(), + generation, + }); + } } } - Some((highest_priority, len)) + + // GC the tasks + let mut count = 0; + for task in tasks[..tasks_to_collect].iter() { + backend.with_task(*task, |task| { + if task.run_gc(generation) { + count += 1; + } + }); + } + + ProcessGenerationResult { + priority: Some(max_priority), + count, + } } -} -/// Converts a value to an logarithmic scale. -pub fn to_exp_u8(value: u64) -> u8 { - value - .checked_next_power_of_two() - .unwrap_or(0x7000_0000_0000_0000) - .trailing_zeros() as u8 + /// Run garbage collection on the queue. + pub fn run_gc(&self, backend: &MemoryBackend) -> Option<(GcPriority, usize)> { + let span = + tracing::trace_span!("garbage collection", priority = Empty, count = Empty).entered(); + + let ProcessGenerationResult { priority, count } = self.process_old_generation(backend); + + span.record("count", count); + if let Some(priority) = &priority { + span.record("priority", debug(priority)); + } else { + span.record("priority", ""); + } + + priority.map(|p| (p, count)) + } } diff --git a/crates/turbo-tasks-memory/src/lib.rs b/crates/turbo-tasks-memory/src/lib.rs index 57c491a4554a9..25a0536212132 100644 --- a/crates/turbo-tasks-memory/src/lib.rs +++ b/crates/turbo-tasks-memory/src/lib.rs @@ -7,18 +7,15 @@ #![feature(impl_trait_in_assoc_type)] #![deny(unsafe_op_in_unsafe_fn)] -mod aggregation_tree; +mod aggregation; mod cell; -mod concurrent_priority_queue; mod count_hash_set; mod gc; mod map_guard; mod memory_backend; mod memory_backend_with_pg; mod output; -pub mod stats; mod task; -pub mod viz; pub use memory_backend::MemoryBackend; pub use memory_backend_with_pg::MemoryBackendWithPersistedGraph; diff --git a/crates/turbo-tasks-memory/src/memory_backend.rs b/crates/turbo-tasks-memory/src/memory_backend.rs index ef4d4cdf56e73..a2822316d400c 100644 --- a/crates/turbo-tasks-memory/src/memory_backend.rs +++ b/crates/turbo-tasks-memory/src/memory_backend.rs @@ -1,7 +1,6 @@ use std::{ borrow::{Borrow, Cow}, cell::RefCell, - cmp::min, future::Future, hash::{BuildHasher, BuildHasherDefault, Hash}, pin::Pin, @@ -9,7 +8,7 @@ use std::{ atomic::{AtomicBool, Ordering}, Arc, }, - time::{Duration, Instant}, + time::Duration, }; use anyhow::{bail, Result}; @@ -30,7 +29,7 @@ use turbo_tasks::{ use crate::{ cell::RecomputingCell, - gc::GcQueue, + gc::{GcQueue, PERCENTAGE_IDLE_TARGET_MEMORY, PERCENTAGE_TARGET_MEMORY}, output::Output, task::{Task, TaskDependency, TaskDependencySet, DEPENDENCIES_TO_TRACK}, }; @@ -84,11 +83,15 @@ impl MemoryBackend { let id = self.backend_job_id_factory.get(); // SAFETY: This is a fresh id unsafe { - self.backend_jobs.insert(*id, job); + self.backend_jobs.insert(*id as usize, job); } id } + pub(crate) fn has_gc(&self) -> bool { + self.gc_queue.is_some() + } + fn try_get_output Result>( &self, id: TaskId, @@ -110,62 +113,48 @@ impl MemoryBackend { #[inline(always)] pub fn with_task(&self, id: TaskId, func: impl FnOnce(&Task) -> T) -> T { - func(self.memory_tasks.get(*id).unwrap()) + func(self.memory_tasks.get(*id as usize).unwrap()) } #[inline(always)] pub fn task(&self, id: TaskId) -> &Task { - self.memory_tasks.get(*id).unwrap() - } - - pub fn on_task_might_become_inactive(&self, task: TaskId) { - if let Some(gc_queue) = &self.gc_queue { - gc_queue.task_might_become_inactive(task); - } + self.memory_tasks.get(*id as usize).unwrap() } - pub fn on_task_flagged_inactive(&self, task: TaskId, compute_duration: Duration) { + /// Runs the garbage collection until reaching the target memory. An `idle` + /// garbage collection has a lower target memory. Returns true, when + /// memory was collected. + pub fn run_gc( + &self, + idle: bool, + _turbo_tasks: &dyn TurboTasksBackendApi, + ) -> bool { if let Some(gc_queue) = &self.gc_queue { - gc_queue.task_flagged_inactive(task, compute_duration); - } - } + let mut did_something = false; + loop { + let mem_limit = self.memory_limit; - pub fn run_gc(&self, idle: bool, turbo_tasks: &dyn TurboTasksBackendApi) { - if let Some(gc_queue) = &self.gc_queue { - const MAX_COLLECT_FACTOR: u8 = u8::MAX / 8; - - let mem_limit = self.memory_limit; - - let usage = turbo_tasks_malloc::TurboMalloc::memory_usage(); - let target = if idle { - mem_limit * 3 / 4 - } else { - mem_limit * 7 / 8 - }; - if usage < target { - if idle { - // Always run propagation when idle - gc_queue.run_gc(0, self, turbo_tasks); + let usage = turbo_tasks_malloc::TurboMalloc::memory_usage(); + let target = if idle { + mem_limit * PERCENTAGE_IDLE_TARGET_MEMORY / 100 + } else { + mem_limit * PERCENTAGE_TARGET_MEMORY / 100 + }; + if usage < target { + return did_something; } - return; - } - - let collect_factor = min( - MAX_COLLECT_FACTOR as usize, - (usage - target) * u8::MAX as usize / (mem_limit - target), - ) as u8; - let collected = gc_queue.run_gc(collect_factor, self, turbo_tasks); + let collected = gc_queue.run_gc(self); - if idle { - if let Some((_collected, _count, _stats)) = collected { - let job = self.create_backend_job(Job::GarbageCollection); - turbo_tasks.schedule_backend_background_job(job); - } else { - self.idle_gc_active.store(false, Ordering::Release); + // Collecting less than 100 tasks is not worth it + if !collected.map_or(false, |(_, count)| count > 100) { + return true; } + + did_something = true; } } + false } fn insert_and_connect_fresh_task( @@ -179,7 +168,7 @@ impl MemoryBackend { ) -> TaskId { let new_id = new_id.into(); // Safety: We have a fresh task id that nobody knows about yet - unsafe { self.memory_tasks.insert(*new_id, task) }; + unsafe { self.memory_tasks.insert(*new_id as usize, task) }; let result_task = match task_cache.entry(key) { Entry::Vacant(entry) => { // This is the most likely case @@ -188,12 +177,14 @@ impl MemoryBackend { } Entry::Occupied(entry) => { // Safety: We have a fresh task id that nobody knows about yet + let task_id = *entry.get(); + drop(entry); unsafe { - self.memory_tasks.remove(*new_id); + self.memory_tasks.remove(*new_id as usize); let new_id = Unused::new_unchecked(new_id); turbo_tasks.reuse_task_id(new_id); } - *entry.get() + task_id } }; self.connect_task_child(parent_task, result_task, turbo_tasks); @@ -211,11 +202,15 @@ impl MemoryBackend { K: Borrow + Hash + Eq, Q: Hash + Eq + ?Sized, { - task_cache.get(key).map(|task| { - self.connect_task_child(parent_task, *task, turbo_tasks); - - *task - }) + task_cache + .get(key) + // Avoid holding the lock for too long + .map(|task_ref| *task_ref) + .map(|task_id| { + self.connect_task_child(parent_task, task_id, turbo_tasks); + + task_id + }) } pub(crate) fn schedule_when_dirty_from_aggregation( @@ -314,17 +309,29 @@ impl Backend for MemoryBackend { &self, task_id: TaskId, duration: Duration, - instant: Instant, + memory_usage: usize, stateful: bool, turbo_tasks: &dyn TurboTasksBackendApi, ) -> bool { + let generation = if let Some(gc_queue) = &self.gc_queue { + gc_queue.generation() + } else { + 0 + }; let reexecute = self.with_task(task_id, |task| { - task.execution_completed(duration, instant, stateful, self, turbo_tasks) + task.execution_completed( + duration, + memory_usage, + generation, + stateful, + self, + turbo_tasks, + ) }); if !reexecute { - self.run_gc(false, turbo_tasks); if let Some(gc_queue) = &self.gc_queue { - gc_queue.task_executed(task_id, duration); + gc_queue.task_executed(task_id); + self.run_gc(false, turbo_tasks); } } reexecute @@ -381,7 +388,7 @@ impl Backend for MemoryBackend { } else { Task::add_dependency_to_current(TaskDependency::Cell(task_id, index)); self.with_task(task_id, |task| { - match task.with_cell_mut(index, |cell| { + match task.with_cell_mut(index, self.gc_queue.as_ref(), |cell| { cell.read_content( reader, move || format!("{task_id} {index}"), @@ -418,7 +425,7 @@ impl Backend for MemoryBackend { turbo_tasks: &dyn TurboTasksBackendApi, ) -> Result> { self.with_task(task_id, |task| { - match task.with_cell_mut(index, |cell| { + match task.with_cell_mut(index, self.gc_queue.as_ref(), |cell| { cell.read_content_untracked( move || format!("{task_id}"), move || format!("reading {} {} untracked", task_id, index), @@ -478,7 +485,9 @@ impl Backend for MemoryBackend { turbo_tasks: &dyn TurboTasksBackendApi, ) { self.with_task(task, |task| { - task.with_cell_mut(index, |cell| cell.assign(content, turbo_tasks)) + task.with_cell_mut(index, self.gc_queue.as_ref(), |cell| { + cell.assign(content, turbo_tasks) + }) }) } @@ -489,7 +498,7 @@ impl Backend for MemoryBackend { turbo_tasks: &'a dyn TurboTasksBackendApi, ) -> Pin + Send + 'a>> { // SAFETY: id will not be reused until with job is done - if let Some(job) = unsafe { self.backend_jobs.take(*id) } { + if let Some(job) = unsafe { self.backend_jobs.take(*id as usize) } { Box::pin(async move { job.run(self, turbo_tasks).await; // SAFETY: This id will no longer be used @@ -525,7 +534,6 @@ impl Backend for MemoryBackend { // control of the task *unsafe { id.get_unchecked() }, task_type.clone(), - turbo_tasks.stats_type(), ); self.insert_and_connect_fresh_task( parent_task, @@ -561,19 +569,18 @@ impl Backend for MemoryBackend { turbo_tasks: &dyn TurboTasksBackendApi, ) -> TaskId { let id = turbo_tasks.get_fresh_task_id(); - let stats_type = turbo_tasks.stats_type(); let id = id.into(); match task_type { TransientTaskType::Root(f) => { - let task = Task::new_root(id, move || f() as _, stats_type); + let task = Task::new_root(id, move || f() as _); // SAFETY: We have a fresh task id where nobody knows about yet - unsafe { self.memory_tasks.insert(*id, task) }; + unsafe { self.memory_tasks.insert(*id as usize, task) }; Task::set_root(id, self, turbo_tasks); } TransientTaskType::Once(f) => { - let task = Task::new_once(id, f, stats_type); + let task = Task::new_once(id, f); // SAFETY: We have a fresh task id where nobody knows about yet - unsafe { self.memory_tasks.insert(*id, task) }; + unsafe { self.memory_tasks.insert(*id as usize, task) }; Task::set_once(id, self, turbo_tasks); } }; @@ -601,7 +608,12 @@ impl Job { match self { Job::GarbageCollection => { let _guard = trace_span!("Job::GarbageCollection").entered(); - backend.run_gc(true, turbo_tasks); + if backend.run_gc(true, turbo_tasks) { + let job = backend.create_backend_job(Job::GarbageCollection); + turbo_tasks.schedule_backend_background_job(job); + } else { + backend.idle_gc_active.store(false, Ordering::Release); + } } } } diff --git a/crates/turbo-tasks-memory/src/memory_backend_with_pg.rs b/crates/turbo-tasks-memory/src/memory_backend_with_pg.rs index 193d437cf79ac..a8fa8104b8af2 100644 --- a/crates/turbo-tasks-memory/src/memory_backend_with_pg.rs +++ b/crates/turbo-tasks-memory/src/memory_backend_with_pg.rs @@ -9,7 +9,7 @@ use std::{ atomic::{AtomicU32, AtomicUsize, Ordering}, Mutex, MutexGuard, }, - time::{Duration, Instant}, + time::Duration, }; use anyhow::{anyhow, Result}; @@ -184,7 +184,7 @@ impl MemoryBackendWithPersistedGraph

{ task: TaskId, turbo_tasks: &dyn TurboTasksBackendApi>, ) -> (MutexGuard<'_, TaskState>, &Task) { - let task_info = self.tasks.get(*task).unwrap(); + let task_info = self.tasks.get(*task as usize).unwrap(); let mut state = task_info.task_state.lock().unwrap(); self.ensure_task_initialized(task, task_info, &mut state, turbo_tasks); (state, task_info) @@ -195,7 +195,7 @@ impl MemoryBackendWithPersistedGraph

{ task: TaskId, turbo_tasks: &dyn TurboTasksBackendApi>, ) -> (MutexGuard<'_, TaskState>, &Task) { - let task_info = self.tasks.get(*task).unwrap(); + let task_info = self.tasks.get(*task as usize).unwrap(); loop { let mut delayed_activate = Vec::new(); let mut state = task_info.task_state.lock().unwrap(); @@ -391,7 +391,7 @@ impl MemoryBackendWithPersistedGraph

{ let id = self.background_job_id_factory.get(); // SAFETY: It's a fresh id unsafe { - self.background_jobs.insert(*id, job); + self.background_jobs.insert(*id as usize, job); } turbo_tasks.schedule_backend_background_job(id); } @@ -481,7 +481,7 @@ impl MemoryBackendWithPersistedGraph

{ delayed_activate: &mut Vec, turbo_tasks: &dyn TurboTasksBackendApi>, ) { - let task_info = self.tasks.get(*task).unwrap(); + let task_info = self.tasks.get(*task as usize).unwrap(); let prev = task_info.active_parents.fetch_add(by, Ordering::Relaxed); if prev == 0 { // only the connect() call that increases from 0 is responsible for activating @@ -633,7 +633,7 @@ impl MemoryBackendWithPersistedGraph

{ delayed_deactivate: &mut Vec, turbo_tasks: &dyn TurboTasksBackendApi>, ) { - let task_info = self.tasks.get(*task).unwrap(); + let task_info = self.tasks.get(*task as usize).unwrap(); let prev = task_info.active_parents.fetch_sub(by, Ordering::Relaxed); if prev == by { // count reached zero @@ -1048,7 +1048,7 @@ impl Backend for MemoryBackendWithPersistedGraph

{ } fn get_task_description(&self, task: TaskId) -> String { - let task_info = self.tasks.get(*task).unwrap(); + let task_info = self.tasks.get(*task as usize).unwrap(); format!("{:?}", task_info.task_type) } @@ -1153,7 +1153,7 @@ impl Backend for MemoryBackendWithPersistedGraph

{ &self, task: TaskId, duration: Duration, - _instant: Instant, + _memory_usage: usize, _stateful: bool, turbo_tasks: &dyn TurboTasksBackendApi>, ) -> bool { @@ -1202,10 +1202,11 @@ impl Backend for MemoryBackendWithPersistedGraph

{ } if has_changes || is_dirty_persisted { self.need_persisting.insert(task); - self.persist_queue_by_duration[*task % self.persist_queue_by_duration.len()] - .lock() - .unwrap() - .push((duration, task)); + self.persist_queue_by_duration + [*task as usize % self.persist_queue_by_duration.len()] + .lock() + .unwrap() + .push((duration, task)); self.increase_persist_workers(1, turbo_tasks); } } @@ -1234,7 +1235,7 @@ impl Backend for MemoryBackendWithPersistedGraph

{ }); } // SAFETY: We are the only owner of this id - let job = unsafe { self.background_jobs.take(*id) }; + let job = unsafe { self.background_jobs.take(*id as usize) }; unsafe { self.background_job_id_factory.reuse(id); } @@ -1543,14 +1544,14 @@ impl Backend for MemoryBackendWithPersistedGraph

{ }; // SAFETY: It's a fresh task id unsafe { - self.tasks.insert(*task, new_task); + self.tasks.insert(*task as usize, new_task); } match self.cache.entry(task_type) { Entry::Occupied(e) => { let existing_task = *e.into_ref(); // SAFETY: We are still the only owner of this task and id unsafe { - self.tasks.remove(*task); + self.tasks.remove(*task as usize); let task = Unused::new_unchecked(task); turbo_tasks.reuse_task_id(task); } @@ -1601,7 +1602,7 @@ impl Backend for MemoryBackendWithPersistedGraph

{ }; // SAFETY: It's a fresh task id unsafe { - self.tasks.insert(*task, new_task); + self.tasks.insert(*task as usize, new_task); } self.only_known_to_memory_tasks.insert(task); task @@ -1631,7 +1632,7 @@ impl<'a, P: PersistedGraph> PersistedGraphApi for MemoryBackendPersistedGraphApi let task = task.into(); // SAFETY: It's a fresh task id unsafe { - self.backend.tasks.insert(*task, new_task); + self.backend.tasks.insert(*task as usize, new_task); } match cache.entry(task_type) { Entry::Occupied(e) => { @@ -1651,7 +1652,7 @@ impl<'a, P: PersistedGraph> PersistedGraphApi for MemoryBackendPersistedGraphApi } fn lookup_task_type(&self, id: TaskId) -> &PersistentTaskType { - let task = self.backend.tasks.get(*id).unwrap(); + let task = self.backend.tasks.get(*id as usize).unwrap(); match &task.task_type { TaskType::Persistent(ty) => ty, _ => panic!("lookup_task_type should only be used for PersistentTaskType"), diff --git a/crates/turbo-tasks-memory/src/output.rs b/crates/turbo-tasks-memory/src/output.rs index 443b5d5e2d267..4b74dfe9de9e9 100644 --- a/crates/turbo-tasks-memory/src/output.rs +++ b/crates/turbo-tasks-memory/src/output.rs @@ -95,10 +95,6 @@ impl Output { } } - pub fn dependent_tasks(&self) -> &TaskIdSet { - &self.dependent_tasks - } - pub fn gc_drop(self, turbo_tasks: &dyn TurboTasksBackendApi) { // notify if !self.dependent_tasks.is_empty() { diff --git a/crates/turbo-tasks-memory/src/stats.rs b/crates/turbo-tasks-memory/src/stats.rs deleted file mode 100644 index 83e65d456fd77..0000000000000 --- a/crates/turbo-tasks-memory/src/stats.rs +++ /dev/null @@ -1,337 +0,0 @@ -use std::{ - cmp::{ - max, {self}, - }, - collections::{hash_map::Entry, HashMap, HashSet, VecDeque}, - fmt::Display, - mem::take, - time::Duration, -}; - -use turbo_tasks::{registry, FunctionId, TaskId, TraitTypeId}; - -use crate::{ - task::{Task, TaskStatsInfo}, - MemoryBackend, -}; - -pub struct StatsReferences { - pub tasks: Vec<(ReferenceType, TaskId)>, -} - -#[derive(PartialEq, Eq, Hash, Clone, Debug)] -pub enum StatsTaskType { - Root(TaskId), - Once(TaskId), - Native(FunctionId), - ResolveNative(FunctionId), - ResolveTrait(TraitTypeId, String), - Collectibles(TraitTypeId), -} - -impl Display for StatsTaskType { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - StatsTaskType::Root(_) => write!(f, "root"), - StatsTaskType::Once(_) => write!(f, "once"), - StatsTaskType::Collectibles(t) => { - write!(f, "read collectibles {}", registry::get_trait(*t).name) - } - StatsTaskType::Native(nf) => write!(f, "{}", registry::get_function(*nf).name), - StatsTaskType::ResolveNative(nf) => { - write!(f, "resolve {}", registry::get_function(*nf).name) - } - StatsTaskType::ResolveTrait(t, n) => { - write!(f, "resolve trait {}::{}", registry::get_trait(*t).name, n) - } - } - } -} - -#[derive(Default, Clone, Debug)] -pub struct ReferenceStats { - pub count: usize, -} - -#[derive(PartialEq, Eq, Hash, Clone, Debug, Copy)] -pub enum ReferenceType { - Child, - Dependency, - Input, -} - -#[derive(Clone, Debug)] -pub struct ExportedTaskStats { - pub count: usize, - pub unloaded_count: usize, - pub executions: Option, - pub total_duration: Option, - pub total_current_duration: Duration, - pub total_update_duration: Duration, - pub max_duration: Duration, - pub references: HashMap<(ReferenceType, StatsTaskType), ReferenceStats>, -} - -impl Default for ExportedTaskStats { - fn default() -> Self { - Self { - count: 0, - unloaded_count: 0, - executions: None, - total_duration: None, - total_current_duration: Duration::ZERO, - total_update_duration: Duration::ZERO, - max_duration: Duration::ZERO, - references: Default::default(), - } - } -} - -pub struct Stats { - tasks: HashMap, -} - -impl Default for Stats { - fn default() -> Self { - Self::new() - } -} - -impl Stats { - pub fn new() -> Self { - Self { - tasks: Default::default(), - } - } - - pub fn add(&mut self, backend: &MemoryBackend, task: &Task) { - self.add_conditional(backend, task, |_, _| true) - } - - pub fn add_conditional( - &mut self, - backend: &MemoryBackend, - task: &Task, - condition: impl FnOnce(&StatsTaskType, &TaskStatsInfo) -> bool, - ) { - let info = task.get_stats_info(backend); - let ty = task.get_stats_type(); - if !condition(&ty, &info) { - return; - } - let TaskStatsInfo { - total_duration, - last_duration, - executions, - unloaded, - } = info; - let stats = self.tasks.entry(ty).or_default(); - stats.count += 1; - if let Some(total_duration) = total_duration { - *stats.total_duration.get_or_insert(Duration::ZERO) += total_duration; - } - if unloaded { - stats.unloaded_count += 1 - } - stats.total_current_duration += last_duration; - if executions.map(|executions| executions > 1).unwrap_or(true) { - stats.total_update_duration += last_duration; - } - stats.max_duration = max(stats.max_duration, last_duration); - if let Some(executions) = executions { - *stats.executions.get_or_insert(0) += executions; - } - - let StatsReferences { tasks, .. } = task.get_stats_references(); - let set: HashSet<_> = tasks.into_iter().collect(); - for (ref_type, task) in set { - backend.with_task(task, |task| { - let ty = task.get_stats_type(); - let ref_stats = stats.references.entry((ref_type, ty)).or_default(); - ref_stats.count += 1; - }) - } - } - - pub fn add_id(&mut self, backend: &MemoryBackend, id: TaskId) { - backend.with_task(id, |task| { - self.add(backend, task); - }); - } - - pub fn add_id_conditional( - &mut self, - backend: &MemoryBackend, - id: TaskId, - condition: impl FnOnce(&StatsTaskType, &TaskStatsInfo) -> bool, - ) { - backend.with_task(id, |task| { - self.add_conditional(backend, task, condition); - }); - } - - pub fn merge_resolve(&mut self) { - self.merge(|ty, _stats| match ty { - StatsTaskType::Root(_) - | StatsTaskType::Once(_) - | StatsTaskType::Native(_) - | StatsTaskType::Collectibles(..) => false, - StatsTaskType::ResolveNative(_) | StatsTaskType::ResolveTrait(_, _) => true, - }) - } - - pub fn merge(&mut self, mut select: impl FnMut(&StatsTaskType, &ExportedTaskStats) -> bool) { - let merged: HashMap<_, _> = self - .tasks - .extract_if(|ty, stats| select(ty, stats)) - .collect(); - - for stats in self.tasks.values_mut() { - fn merge_refs( - refs: HashMap<(ReferenceType, StatsTaskType), ReferenceStats>, - merged: &HashMap, - ) -> HashMap<(ReferenceType, StatsTaskType), ReferenceStats> { - refs.into_iter() - .flat_map(|((ref_ty, ty), stats)| { - if let Some(merged_stats) = merged.get(&ty) { - if ref_ty == ReferenceType::Child { - merge_refs(merged_stats.references.clone(), merged) - .into_iter() - .map(|((ref_ty, ty), _)| ((ref_ty, ty), stats.clone())) - .collect() - } else { - vec![] - } - } else { - vec![((ref_ty, ty), stats)] - } - }) - .collect() - } - stats.references = merge_refs(take(&mut stats.references), &merged); - } - } - - pub fn treeify(&self, tree_ref_type: ReferenceType) -> GroupTree { - let mut incoming_references_count = self - .tasks - .keys() - .map(|ty| (ty, 0)) - .collect::>(); - for stats in self.tasks.values() { - for (ref_type, ty) in stats.references.keys() { - if ref_type == &tree_ref_type { - *incoming_references_count.entry(ty).or_default() += 1; - } - } - } - let mut root_queue = incoming_references_count.into_iter().collect::>(); - root_queue.sort_by_key(|(_, c)| *c); - - let mut task_placement: HashMap<&StatsTaskType, Option<&StatsTaskType>> = HashMap::new(); - fn get_path<'a>( - ty: Option<&'a StatsTaskType>, - task_placement: &HashMap<&'a StatsTaskType, Option<&'a StatsTaskType>>, - ) -> Vec<&'a StatsTaskType> { - if let Some(mut ty) = ty { - let mut path = vec![ty]; - while let Some(parent) = task_placement[ty] { - ty = parent; - path.push(ty); - } - path.reverse(); - path - } else { - Vec::new() - } - } - fn find_common<'a>( - p1: Vec<&'a StatsTaskType>, - p2: Vec<&'a StatsTaskType>, - ) -> Option<&'a StatsTaskType> { - let mut i = cmp::min(p1.len(), p2.len()); - loop { - if i == 0 { - return None; - } - i -= 1; - if p1[i] == p2[i] { - return Some(p1[i]); - } - } - } - for (root, _) in root_queue.into_iter() { - if task_placement.contains_key(root) { - continue; - } - let mut queue: VecDeque<(&StatsTaskType, Option<&StatsTaskType>)> = - [(root, None)].into_iter().collect(); - - while let Some((ty, placement)) = queue.pop_front() { - match task_placement.entry(ty) { - Entry::Occupied(e) => { - let current_placement = *e.get(); - if placement != current_placement { - let new_placement = find_common( - get_path(placement, &task_placement), - get_path(current_placement, &task_placement), - ); - task_placement.insert(ty, new_placement); - } - } - Entry::Vacant(e) => { - if let Some(task) = self.tasks.get(ty) { - e.insert(placement); - - for (ref_type, child_ty) in task.references.keys() { - if ref_type == &tree_ref_type { - queue.push_back((child_ty, Some(ty))); - } - } - } - } - } - } - } - - let mut children: HashMap, Vec<&StatsTaskType>> = HashMap::new(); - for (child, parent) in task_placement { - children.entry(parent).or_default().push(child); - } - - fn into_group<'a>( - tasks: &HashMap, - children: &HashMap, Vec<&'a StatsTaskType>>, - ty: Option<&'a StatsTaskType>, - ) -> GroupTree { - let inner = &children[&ty]; - let inner_with_children = inner.iter().filter(|c| children.contains_key(&Some(*c))); - let leafs = inner.iter().filter(|c| !children.contains_key(&Some(*c))); - let task_types: Vec<_> = leafs.map(|&ty| (ty.clone(), tasks[ty].clone())).collect(); - GroupTree { - primary: ty.map(|ty| (ty.clone(), tasks[ty].clone())), - children: inner_with_children - .map(|ty| into_group(tasks, children, Some(ty))) - .collect(), - task_types, - } - } - - if children.is_empty() { - GroupTree { - primary: None, - children: Vec::new(), - task_types: Vec::new(), - } - } else { - into_group(&self.tasks, &children, None) - } - } -} - -#[derive(Debug)] -pub struct GroupTree { - pub primary: Option<(StatsTaskType, ExportedTaskStats)>, - pub children: Vec, - pub task_types: Vec<(StatsTaskType, ExportedTaskStats)>, -} diff --git a/crates/turbo-tasks-memory/src/task.rs b/crates/turbo-tasks-memory/src/task.rs index 856a5ad8dc2ce..cd9e3cd4fca69 100644 --- a/crates/turbo-tasks-memory/src/task.rs +++ b/crates/turbo-tasks-memory/src/task.rs @@ -1,21 +1,13 @@ -mod aggregation; -mod meta_state; -mod stats; - use std::{ borrow::Cow, cell::RefCell, - cmp::{max, Reverse}, - collections::{HashMap, HashSet}, - fmt::{ - Debug, Display, Formatter, {self}, - }, + fmt::{self, Debug, Display, Formatter}, future::Future, hash::{BuildHasherDefault, Hash}, mem::{replace, take}, pin::Pin, - sync::Arc, - time::{Duration, Instant}, + sync::{atomic::AtomicU32, Arc}, + time::Duration, }; use anyhow::Result; @@ -24,22 +16,23 @@ use nohash_hasher::BuildNoHashHasher; use parking_lot::{Mutex, RwLock}; use rustc_hash::FxHasher; use smallvec::SmallVec; -use stats::TaskStats; use tokio::task_local; use tracing::Span; use turbo_tasks::{ backend::{PersistentTaskType, TaskExecutionSpec}, event::{Event, EventListener}, - get_invalidator, registry, CellId, Invalidator, NativeFunction, RawVc, StatsType, TaskId, - TaskIdSet, TraitType, TraitTypeId, TurboTasksBackendApi, ValueTypeId, + get_invalidator, registry, CellId, Invalidator, NativeFunction, RawVc, TaskId, TaskIdSet, + TraitType, TraitTypeId, TurboTasksBackendApi, ValueTypeId, }; use crate::{ - aggregation_tree::{aggregation_info, ensure_thresholds, AggregationInfoGuard}, + aggregation::{ + aggregation_data, handle_new_edge, prepare_aggregation_data, query_root_info, + AggregationDataGuard, PreparedOperation, + }, cell::Cell, - gc::{to_exp_u8, GcPriority, GcStats, GcTaskState}, + gc::{GcQueue, GcTaskState}, output::{Output, OutputContent}, - stats::{ReferenceType, StatsReferences, StatsTaskType}, task::aggregation::{TaskAggregationContext, TaskChange}, MemoryBackend, }; @@ -47,6 +40,9 @@ use crate::{ pub type NativeTaskFuture = Pin> + Send>>; pub type NativeTaskFn = Box NativeTaskFuture + Send + Sync>; +mod aggregation; +mod meta_state; + #[derive(Hash, Copy, Clone, PartialEq, Eq)] pub enum TaskDependency { Output(TaskId), @@ -138,6 +134,8 @@ pub struct Task { /// The mutable state of the task /// Unset state is equal to a Dirty task that has not been executed yet state: RwLock, + /// Atomic in progress counter for graph modification + graph_modification_in_progress_counter: AtomicU32, } impl Debug for Task { @@ -164,7 +162,7 @@ impl Debug for Task { /// The full state of a [Task], it includes all information. struct TaskState { - aggregation_leaf: TaskAggregationTreeLeaf, + aggregation_node: TaskAggregationNode, // TODO using a Atomic might be possible here /// More flags of task state, where not all combinations are possible. @@ -189,18 +187,12 @@ struct TaskState { // GC state: gc: GcTaskState, - - // Stats: - stats: TaskStats, } impl TaskState { - fn new( - description: impl Fn() -> String + Send + Sync + 'static, - stats_type: StatsType, - ) -> Self { + fn new(description: impl Fn() -> String + Send + Sync + 'static) -> Self { Self { - aggregation_leaf: TaskAggregationTreeLeaf::new(), + aggregation_node: TaskAggregationNode::new(), state_type: Dirty { event: Event::new(move || format!("TaskState({})::event", description())), outdated_dependencies: Default::default(), @@ -212,18 +204,14 @@ impl TaskState { prepared_type: PrepareTaskType::None, cells: Default::default(), gc: Default::default(), - stats: TaskStats::new(stats_type), #[cfg(feature = "track_wait_dependencies")] last_waiting_task: Default::default(), } } - fn new_scheduled( - description: impl Fn() -> String + Send + Sync + 'static, - stats_type: StatsType, - ) -> Self { + fn new_scheduled(description: impl Fn() -> String + Send + Sync + 'static) -> Self { Self { - aggregation_leaf: TaskAggregationTreeLeaf::new(), + aggregation_node: TaskAggregationNode::new(), state_type: Scheduled { event: Event::new(move || format!("TaskState({})::event", description())), outdated_dependencies: Default::default(), @@ -235,7 +223,6 @@ impl TaskState { prepared_type: PrepareTaskType::None, cells: Default::default(), gc: Default::default(), - stats: TaskStats::new(stats_type), #[cfg(feature = "track_wait_dependencies")] last_waiting_task: Default::default(), } @@ -248,14 +235,13 @@ impl TaskState { /// A Task can get into this state when it is unloaded by garbage collection, /// but is still attached to parents and aggregated. struct PartialTaskState { - stats_type: StatsType, - aggregation_leaf: TaskAggregationTreeLeaf, + aggregation_node: TaskAggregationNode, } impl PartialTaskState { fn into_full(self, description: impl Fn() -> String + Send + Sync + 'static) -> TaskState { TaskState { - aggregation_leaf: self.aggregation_leaf, + aggregation_node: self.aggregation_node, state_type: Dirty { event: Event::new(move || format!("TaskState({})::event", description())), outdated_dependencies: Default::default(), @@ -267,7 +253,6 @@ impl PartialTaskState { output: Default::default(), cells: Default::default(), gc: Default::default(), - stats: TaskStats::new(self.stats_type), } } } @@ -276,9 +261,7 @@ impl PartialTaskState { /// being referenced by any parent. This state is stored inlined instead of in a /// [Box] to reduce the memory consumption. Make sure to not add more fields /// than the size of a [Box]. -struct UnloadedTaskState { - stats_type: StatsType, -} +struct UnloadedTaskState {} #[cfg(test)] #[test] @@ -289,7 +272,7 @@ fn test_unloaded_task_state_size() { impl UnloadedTaskState { fn into_full(self, description: impl Fn() -> String + Send + Sync + 'static) -> TaskState { TaskState { - aggregation_leaf: TaskAggregationTreeLeaf::new(), + aggregation_node: TaskAggregationNode::new(), state_type: Dirty { event: Event::new(move || format!("TaskState({})::event", description())), outdated_dependencies: Default::default(), @@ -301,14 +284,12 @@ impl UnloadedTaskState { output: Default::default(), cells: Default::default(), gc: Default::default(), - stats: TaskStats::new(self.stats_type), } } fn into_partial(self) -> PartialTaskState { PartialTaskState { - aggregation_leaf: TaskAggregationTreeLeaf::new(), - stats_type: self.stats_type, + aggregation_node: TaskAggregationNode::new(), } } } @@ -411,41 +392,34 @@ enum TaskStateType { /// Invalid execution is happening /// - /// on finish this will move to Dirty or Scheduled depending on active flag + /// on finish this will move to Scheduled InProgressDirty { event: Event }, } use TaskStateType::*; use self::{ - aggregation::{Aggregated, RootInfoType, RootType, TaskAggregationTreeLeaf, TaskGuard}, + aggregation::{ActiveQuery, RootType, TaskAggregationNode, TaskGuard}, meta_state::{ FullTaskWriteGuard, TaskMetaState, TaskMetaStateReadGuard, TaskMetaStateWriteGuard, }, }; impl Task { - pub(crate) fn new_persistent( - id: TaskId, - task_type: Arc, - stats_type: StatsType, - ) -> Self { + pub(crate) fn new_persistent(id: TaskId, task_type: Arc) -> Self { let ty = TaskType::Persistent { ty: task_type }; let description = Self::get_event_description_static(id, &ty); Self { id, ty, - state: RwLock::new(TaskMetaState::Full(Box::new(TaskState::new( - description, - stats_type, - )))), + state: RwLock::new(TaskMetaState::Full(Box::new(TaskState::new(description)))), + graph_modification_in_progress_counter: AtomicU32::new(0), } } pub(crate) fn new_root( id: TaskId, functor: impl Fn() -> NativeTaskFuture + Sync + Send + 'static, - stats_type: StatsType, ) -> Self { let ty = TaskType::Root(Box::new(Box::new(functor))); let description = Self::get_event_description_static(id, &ty); @@ -454,15 +428,14 @@ impl Task { ty, state: RwLock::new(TaskMetaState::Full(Box::new(TaskState::new_scheduled( description, - stats_type, )))), + graph_modification_in_progress_counter: AtomicU32::new(0), } } pub(crate) fn new_once( id: TaskId, functor: impl Future> + Send + 'static, - stats_type: StatsType, ) -> Self { let ty = TaskType::Once(Box::new(Mutex::new(Some(Box::pin(functor))))); let description = Self::get_event_description_static(id, &ty); @@ -471,8 +444,8 @@ impl Task { ty, state: RwLock::new(TaskMetaState::Full(Box::new(TaskState::new_scheduled( description, - stats_type, )))), + graph_modification_in_progress_counter: AtomicU32::new(0), } } @@ -493,7 +466,7 @@ impl Task { { Self::set_root_type( &aggregation_context, - &mut aggregation_context.aggregation_info(id).lock(), + &mut aggregation_context.aggregation_data(id), RootType::Root, ); } @@ -507,19 +480,15 @@ impl Task { ) { let mut aggregation_context = TaskAggregationContext::new(turbo_tasks, backend); { - let aggregation_info = &aggregation_context.aggregation_info(id); - Self::set_root_type( - &aggregation_context, - &mut aggregation_info.lock(), - RootType::Once, - ); + let mut aggregation_guard = aggregation_context.aggregation_data(id); + Self::set_root_type(&aggregation_context, &mut aggregation_guard, RootType::Once); } aggregation_context.apply_queued_updates(); } fn set_root_type( aggregation_context: &TaskAggregationContext, - aggregation: &mut AggregationInfoGuard, + aggregation: &mut AggregationDataGuard>, root_type: RootType, ) { aggregation.root_type = Some(root_type); @@ -540,7 +509,7 @@ impl Task { ) { let mut aggregation_context = TaskAggregationContext::new(turbo_tasks, backend); { - aggregation_context.aggregation_info(id).lock().root_type = None; + aggregation_context.aggregation_data(id).root_type = None; } aggregation_context.apply_queued_updates(); } @@ -628,10 +597,8 @@ impl Task { } TaskDependency::Collectibles(task, trait_type) => { let aggregation_context = TaskAggregationContext::new(turbo_tasks, backend); - let aggregation = aggregation_context.aggregation_info(task); - aggregation - .lock() - .remove_collectible_dependent_task(trait_type, reader); + let mut aggregation = aggregation_context.aggregation_data(task); + aggregation.remove_collectible_dependent_task(trait_type, reader); } } } @@ -724,7 +691,7 @@ impl Task { #[cfg(not(feature = "lazy_remove_children"))] { remove_job = state - .aggregation_leaf + .aggregation_node .remove_children_job(&aggregation_context, outdated_children); } state.state_type = InProgress { @@ -734,7 +701,6 @@ impl Task { outdated_children, outdated_collectibles, }; - state.stats.increment_executions(); } Dirty { .. } => { let state_type = Task::state_string(&state); @@ -887,24 +853,22 @@ impl Task { } } let change_job = state - .aggregation_leaf - .change_job(&aggregation_context, change); + .aggregation_node + .apply_change(&aggregation_context, change); #[cfg(feature = "lazy_remove_children")] let remove_job = if outdated_children.is_empty() { None } else { - Some( - state - .aggregation_leaf - .remove_children_job(&aggregation_context, outdated_children), - ) + Some(state.aggregation_node.handle_lost_edges( + &aggregation_context, + &self.id, + outdated_children, + )) }; drop(state); - change_job(); + change_job.apply(&aggregation_context); #[cfg(feature = "lazy_remove_children")] - if let Some(job) = remove_job { - job(); - } + remove_job.apply(&aggregation_context); } aggregation_context.apply_queued_updates(); } @@ -962,7 +926,8 @@ impl Task { pub(crate) fn execution_completed( &self, duration: Duration, - instant: Instant, + memory_usage: usize, + generation: u32, stateful: bool, backend: &MemoryBackend, turbo_tasks: &dyn TurboTasksBackendApi, @@ -978,8 +943,8 @@ impl Task { let mut state = self.full_state_mut(); state - .stats - .register_execution(duration, turbo_tasks.program_duration_until(instant)); + .gc + .execution_completed(duration, memory_usage, generation); match state.state_type { InProgress { ref mut event, @@ -993,13 +958,15 @@ impl Task { let outdated_children = take(outdated_children); let outdated_collectibles = outdated_collectibles.take_collectibles(); let mut dependencies = take(&mut dependencies); - // This will stay here for longer, so make sure to not consume too much - // memory - dependencies.shrink_to_fit(); - for cells in state.cells.values_mut() { - cells.shrink_to_fit(); + if !backend.has_gc() { + // This will stay here for longer, so make sure to not consume too much + // memory + dependencies.shrink_to_fit(); + for cells in state.cells.values_mut() { + cells.shrink_to_fit(); + } + state.cells.shrink_to_fit(); } - state.cells.shrink_to_fit(); state.stateful = stateful; state.state_type = Done { dependencies }; if !count_as_finished { @@ -1014,18 +981,16 @@ impl Task { change.collectibles.push((trait_type, value, -count)); } } - change_job = Some( - state - .aggregation_leaf - .change_job(&aggregation_context, change), - ); + change_job = state + .aggregation_node + .apply_change(&aggregation_context, change); } #[cfg(feature = "lazy_remove_children")] if !outdated_children.is_empty() { - remove_job = Some( - state - .aggregation_leaf - .remove_children_job(&aggregation_context, outdated_children), + remove_job = state.aggregation_node.handle_lost_edges( + &aggregation_context, + &self.id, + outdated_children, ); } event.notify(usize::MAX); @@ -1049,20 +1014,13 @@ impl Task { if !dependencies.is_empty() { self.clear_dependencies(dependencies, backend, turbo_tasks); } - if let Some(job) = change_job { - job(); - } + change_job.apply(&aggregation_context); #[cfg(feature = "lazy_remove_children")] - if let Some(job) = remove_job { - job(); - } + remove_job.apply(&aggregation_context); } if let TaskType::Once(_) = self.ty { // unset the root type, so tasks below are no longer active - aggregation_context - .aggregation_info(self.id) - .lock() - .root_type = None; + aggregation_context.aggregation_data(self.id).root_type = None; } aggregation_context.apply_queued_updates(); @@ -1088,12 +1046,14 @@ impl Task { return; } + let mut aggregation_context = TaskAggregationContext::new(turbo_tasks, backend); + let active = query_root_info(&aggregation_context, ActiveQuery::default(), self.id); + let state = if force_schedule { TaskMetaStateWriteGuard::Full(self.full_state_mut()) } else { self.state_mut() }; - let mut aggregation_context = TaskAggregationContext::new(turbo_tasks, backend); if let TaskMetaStateWriteGuard::Full(mut state) = state { match state.state_type { Scheduled { .. } | InProgressDirty { .. } => { @@ -1112,14 +1072,15 @@ impl Task { }), outdated_dependencies: take(outdated_dependencies), }; - state.aggregation_leaf.change( + let change_job = state.aggregation_node.apply_change( &aggregation_context, - &TaskChange { + TaskChange { dirty_tasks_update: vec![(self.id, -1)], ..Default::default() }, ); drop(state); + change_job.apply(&aggregation_context); turbo_tasks.schedule(self.id); } else { // already dirty @@ -1129,51 +1090,20 @@ impl Task { Done { ref mut dependencies, } => { - let mut has_set_unfinished = false; let outdated_dependencies = take(dependencies); // add to dirty lists and potentially schedule let description = self.get_event_description(); - let should_schedule = force_schedule - || state - .aggregation_leaf - .get_root_info(&aggregation_context, &RootInfoType::IsActive) - || { - state.aggregation_leaf.change( - &aggregation_context, - &TaskChange { - unfinished: 1, - #[cfg(feature = "track_unfinished")] - unfinished_tasks_update: vec![(self.id, 1)], - dirty_tasks_update: vec![(self.id, 1)], - ..Default::default() - }, - ); - has_set_unfinished = true; - if aggregation_context.take_scheduled_dirty_task(self.id) { - state.aggregation_leaf.change( - &aggregation_context, - &TaskChange { - dirty_tasks_update: vec![(self.id, -1)], - ..Default::default() - }, - ); - true - } else { - false - } - }; - if !has_set_unfinished { - state.aggregation_leaf.change( + let should_schedule = force_schedule || active; + if should_schedule { + let change_job = state.aggregation_node.apply_change( &aggregation_context, - &TaskChange { + TaskChange { unfinished: 1, #[cfg(feature = "track_unfinished")] unfinished_tasks_update: vec![(self.id, 1)], ..Default::default() }, ); - } - if should_schedule { state.state_type = Scheduled { event: Event::new(move || { format!("TaskState({})::event", description()) @@ -1181,12 +1111,23 @@ impl Task { outdated_dependencies, }; drop(state); + change_job.apply(&aggregation_context); if cfg!(feature = "print_task_invalidation") { println!("invalidated Task {{ id: {}, name: {} }}", *self.id, self.ty); } turbo_tasks.schedule(self.id); } else { + let change_job = state.aggregation_node.apply_change( + &aggregation_context, + TaskChange { + unfinished: 1, + #[cfg(feature = "track_unfinished")] + unfinished_tasks_update: vec![(self.id, 1)], + dirty_tasks_update: vec![(self.id, 1)], + ..Default::default() + }, + ); state.state_type = Dirty { event: Event::new(move || { format!("TaskState({})::event", description()) @@ -1194,6 +1135,7 @@ impl Task { outdated_dependencies, }; drop(state); + change_job.apply(&aggregation_context); } } InProgress { @@ -1229,22 +1171,22 @@ impl Task { } else { None }; - let change_job = change.map(|change| { + let change_job = change.and_then(|change| { state - .aggregation_leaf - .change_job(&aggregation_context, change) + .aggregation_node + .apply_change(&aggregation_context, change) }); #[cfg(feature = "lazy_remove_children")] - let remove_job = state - .aggregation_leaf - .remove_children_job(&aggregation_context, outdated_children); + let remove_job = state.aggregation_node.handle_lost_edges( + &aggregation_context, + &self.id, + outdated_children, + ); state.state_type = InProgressDirty { event }; drop(state); - if let Some(job) = change_job { - job(); - } + change_job.apply(&aggregation_context); #[cfg(feature = "lazy_remove_children")] - remove_job(); + remove_job.apply(&aggregation_context); } } } @@ -1256,18 +1198,18 @@ impl Task { backend: &MemoryBackend, turbo_tasks: &dyn TurboTasksBackendApi, ) { - let aggregation_context = TaskAggregationContext::new(turbo_tasks, backend); let mut state = self.full_state_mut(); if let TaskStateType::Dirty { ref mut event, ref mut outdated_dependencies, } = state.state_type { + let mut aggregation_context = TaskAggregationContext::new(turbo_tasks, backend); state.state_type = Scheduled { event: event.take(), outdated_dependencies: take(outdated_dependencies), }; - let job = state.aggregation_leaf.change_job( + let job = state.aggregation_node.apply_change( &aggregation_context, TaskChange { dirty_tasks_update: vec![(self.id, -1)], @@ -1276,7 +1218,8 @@ impl Task { ); drop(state); turbo_tasks.schedule(self.id); - job(); + job.apply(&aggregation_context); + aggregation_context.apply_queued_updates(); } } @@ -1310,6 +1253,7 @@ impl Task { backend: &MemoryBackend, turbo_tasks: &dyn TurboTasksBackendApi, ) { + let _span = tracing::trace_span!("turbo_tasks::recompute", id = *self.id).entered(); self.make_dirty_internal(true, backend, turbo_tasks) } @@ -1326,8 +1270,19 @@ impl Task { } /// Access to a cell. - pub(crate) fn with_cell_mut(&self, index: CellId, func: impl FnOnce(&mut Cell) -> T) -> T { + pub(crate) fn with_cell_mut( + &self, + index: CellId, + gc_queue: Option<&GcQueue>, + func: impl FnOnce(&mut Cell) -> T, + ) -> T { let mut state = self.full_state_mut(); + if let Some(gc_queue) = gc_queue { + let generation = gc_queue.generation(); + if state.gc.on_read(generation) { + gc_queue.task_accessed(self.id); + } + } let list = state.cells.entry(index.type_id).or_default(); let i = index.index as usize; if list.len() <= i { @@ -1362,13 +1317,6 @@ impl Task { } } - /// For testing purposes - pub fn reset_executions(&self) { - if let TaskMetaStateWriteGuard::Full(mut state) = self.state_mut() { - state.stats.reset_executions() - } - } - pub fn is_pending(&self) -> bool { if let TaskMetaStateReadGuard::Full(state) = self.state() { !matches!(state.state_type, TaskStateType::Done { .. }) @@ -1385,94 +1333,6 @@ impl Task { } } - pub fn reset_stats(&self) { - if let TaskMetaStateWriteGuard::Full(mut state) = self.state_mut() { - state.stats.reset(); - } - } - - pub fn get_stats_info(&self, _backend: &MemoryBackend) -> TaskStatsInfo { - match self.state() { - TaskMetaStateReadGuard::Full(state) => { - let (total_duration, last_duration, executions) = match &state.stats { - TaskStats::Essential(stats) => (None, stats.last_duration(), None), - TaskStats::Full(stats) => ( - Some(stats.total_duration()), - stats.last_duration(), - Some(stats.executions()), - ), - }; - - TaskStatsInfo { - total_duration, - last_duration, - executions, - unloaded: false, - } - } - TaskMetaStateReadGuard::Partial(_) => TaskStatsInfo { - total_duration: None, - last_duration: Duration::ZERO, - executions: None, - unloaded: true, - }, - TaskMetaStateReadGuard::Unloaded => TaskStatsInfo { - total_duration: None, - last_duration: Duration::ZERO, - executions: None, - unloaded: true, - }, - } - } - - pub fn get_stats_type(self: &Task) -> StatsTaskType { - match &self.ty { - TaskType::Root(_) => StatsTaskType::Root(self.id), - TaskType::Once(_) => StatsTaskType::Once(self.id), - TaskType::Persistent { ty, .. } => match &**ty { - PersistentTaskType::Native(f, _) => StatsTaskType::Native(*f), - PersistentTaskType::ResolveNative(f, _) => StatsTaskType::ResolveNative(*f), - PersistentTaskType::ResolveTrait(t, n, _) => { - StatsTaskType::ResolveTrait(*t, n.to_string()) - } - }, - } - } - - pub fn get_stats_references(&self) -> StatsReferences { - let mut refs = Vec::new(); - if let TaskMetaStateReadGuard::Full(state) = self.state() { - for child in state.children.iter() { - refs.push((ReferenceType::Child, *child)); - } - if let Done { ref dependencies } = state.state_type { - for dep in dependencies.iter() { - match dep { - TaskDependency::Output(task) - | TaskDependency::Cell(task, _) - | TaskDependency::Collectibles(task, _) => { - refs.push((ReferenceType::Dependency, *task)) - } - } - } - } - } - if let TaskType::Persistent { ty, .. } = &self.ty { - match &**ty { - PersistentTaskType::Native(_, inputs) - | PersistentTaskType::ResolveNative(_, inputs) - | PersistentTaskType::ResolveTrait(_, _, inputs) => { - for input in inputs.iter() { - if let Some(task) = input.get_task_id() { - refs.push((ReferenceType::Input, task)); - } - } - } - } - } - StatsReferences { tasks: refs } - } - fn state_string(state: &TaskState) -> &'static str { match state.state_type { Scheduled { .. } => "scheduled", @@ -1500,21 +1360,7 @@ impl Task { { let mut add_job = None; { - let mut guard = TaskGuard { - id: self.id, - guard: self.state_mut(), - }; - while let Some(thresholds_job) = ensure_thresholds(&aggregation_context, &mut guard) - { - drop(guard); - thresholds_job(); - guard = TaskGuard { - id: self.id, - guard: self.state_mut(), - }; - } - let TaskGuard { guard, .. } = guard; - let mut state = TaskMetaStateWriteGuard::full_from(guard.into_inner(), self); + let mut state = self.full_state_mut(); if state.children.insert(child_id) { #[cfg(feature = "lazy_remove_children")] if let TaskStateType::InProgress { @@ -1522,14 +1368,20 @@ impl Task { } = &mut state.state_type { if outdated_children.remove(&child_id) { + drop(state); + aggregation_context.apply_queued_updates(); return; } } - add_job = Some( - state - .aggregation_leaf - .add_child_job(&aggregation_context, &child_id), - ); + let number_of_children = state.children.len(); + let mut guard = TaskGuard::from_full(self.id, state); + add_job = Some(handle_new_edge( + &aggregation_context, + &mut guard, + &self.id, + &child_id, + number_of_children, + )); } } if let Some(job) = add_job { @@ -1539,22 +1391,14 @@ impl Task { // So it's fine to ignore the race condition existing here. backend.with_task(child_id, |child| { if child.is_dirty() { - let state = self.state(); - let active = match state { - TaskMetaStateReadGuard::Full(state) => state - .aggregation_leaf - .get_root_info(&aggregation_context, &RootInfoType::IsActive), - TaskMetaStateReadGuard::Partial(state) => state - .aggregation_leaf - .get_root_info(&aggregation_context, &RootInfoType::IsActive), - TaskMetaStateReadGuard::Unloaded => false, - }; + let active = + query_root_info(&aggregation_context, ActiveQuery::default(), self.id); if active { child.schedule_when_dirty_from_aggregation(backend, turbo_tasks); } } }); - job(); + job.apply(&aggregation_context); } } aggregation_context.apply_queued_updates(); @@ -1569,34 +1413,35 @@ impl Task { turbo_tasks: &dyn TurboTasksBackendApi, ) -> Result> { let mut aggregation_context = TaskAggregationContext::new(turbo_tasks, backend); - let aggregation_when_strongly_consistent = - strongly_consistent.then(|| aggregation_info(&aggregation_context, &self.id)); - let mut state = self.full_state_mut(); - if let Some(aggregation) = aggregation_when_strongly_consistent { - { - let mut aggregation = aggregation.lock(); - if aggregation.unfinished > 0 { - if aggregation.root_type.is_none() { - Self::set_root_type( - &aggregation_context, - &mut aggregation, - RootType::ReadingStronglyConsistent, - ); - } - let listener = aggregation.unfinished_event.listen_with_note(note); - drop(aggregation); - drop(state); - aggregation_context.apply_queued_updates(); - - return Ok(Err(listener)); - } else if matches!( - aggregation.root_type, - Some(RootType::ReadingStronglyConsistent) - ) { - aggregation.root_type = None; + if strongly_consistent { + prepare_aggregation_data(&aggregation_context, &self.id); + } + let mut state = if strongly_consistent { + let mut aggregation = aggregation_data(&aggregation_context, &self.id); + if aggregation.unfinished > 0 { + if aggregation.root_type.is_none() { + Self::set_root_type( + &aggregation_context, + &mut aggregation, + RootType::ReadingStronglyConsistent, + ); } + let listener = aggregation.unfinished_event.listen_with_note(note); + drop(aggregation); + aggregation_context.apply_queued_updates(); + + return Ok(Err(listener)); + } else if matches!( + aggregation.root_type, + Some(RootType::ReadingStronglyConsistent) + ) { + aggregation.root_type = None; } - } + let state = aggregation.into_inner().into_inner().into_inner(); + TaskMetaStateWriteGuard::full_from(state, self) + } else { + self.full_state_mut() + }; let result = match state.state_type { Done { .. } => { let result = func(&mut state.output)?; @@ -1615,14 +1460,15 @@ impl Task { event, outdated_dependencies: take(outdated_dependencies), }; - state.aggregation_leaf.change( + let change_job = state.aggregation_node.apply_change( &aggregation_context, - &TaskChange { + TaskChange { dirty_tasks_update: vec![(self.id, -1)], ..Default::default() }, ); drop(state); + change_job.apply(&aggregation_context); Ok(Err(listener)) } Scheduled { ref event, .. } @@ -1645,10 +1491,8 @@ impl Task { turbo_tasks: &dyn TurboTasksBackendApi, ) -> AutoMap { let aggregation_context = TaskAggregationContext::new(turbo_tasks, backend); - aggregation_context - .aggregation_info(id) - .lock() - .read_collectibles(trait_type, reader) + let mut aggregation_data = aggregation_context.aggregation_data(id); + aggregation_data.read_collectibles(trait_type, reader) } pub(crate) fn emit_collectible( @@ -1661,14 +1505,15 @@ impl Task { let mut aggregation_context = TaskAggregationContext::new(turbo_tasks, backend); let mut state = self.full_state_mut(); state.collectibles.emit(trait_type, collectible); - state.aggregation_leaf.change( + let change_job = state.aggregation_node.apply_change( &aggregation_context, - &TaskChange { + TaskChange { collectibles: vec![(trait_type, collectible, 1)], ..Default::default() }, ); drop(state); + change_job.apply(&aggregation_context); aggregation_context.apply_queued_updates(); } @@ -1683,325 +1528,85 @@ impl Task { let mut aggregation_context = TaskAggregationContext::new(turbo_tasks, backend); let mut state = self.full_state_mut(); state.collectibles.unemit(trait_type, collectible, count); - state.aggregation_leaf.change( + let change_job = state.aggregation_node.apply_change( &aggregation_context, - &TaskChange { + TaskChange { collectibles: vec![(trait_type, collectible, -(count as i32))], ..Default::default() }, ); drop(state); + change_job.apply(&aggregation_context); aggregation_context.apply_queued_updates(); } - pub(crate) fn gc_check_inactive(&self, backend: &MemoryBackend) { - if let TaskMetaStateWriteGuard::Full(mut state) = self.state_mut() { - if state.gc.inactive { - return; - } - state.gc.inactive = true; - backend.on_task_flagged_inactive(self.id, state.stats.last_duration()); - for &child in state.children.iter() { - backend.on_task_might_become_inactive(child); - } - } - } - - pub(crate) fn run_gc( - &self, - now_relative_to_start: Duration, - max_priority: GcPriority, - task_duration_cache: &mut HashMap>, - stats: &mut GcStats, - backend: &MemoryBackend, - turbo_tasks: &dyn TurboTasksBackendApi, - ) -> Option { + pub(crate) fn run_gc(&self, generation: u32) -> bool { if !self.is_pure() { - stats.no_gc_needed += 1; - return None; + return false; } + let mut cells_to_drop = Vec::new(); - // We don't want to access other tasks under this task lock, so we aggregate - // missing information first, gather it and then retry. - let mut missing_durations = Vec::new(); - loop { - // This might be slightly inaccurate as we don't hold the lock for the whole - // duration so it might be too large when concurrent modifications - // happen, but that's fine. - let mut dependent_tasks_compute_duration = Duration::ZERO; - let mut included_tasks = HashSet::with_hasher(BuildNoHashHasher::::default()); - // Fill up missing durations - for task_id in missing_durations.drain(..) { - backend.with_task(task_id, |task| { - let duration = task.gc_compute_duration(); - task_duration_cache.insert(task_id, duration); - dependent_tasks_compute_duration += duration; - }) + + let result = if let TaskMetaStateWriteGuard::Full(mut state) = self.state_mut() { + if state.gc.generation > generation || state.stateful { + return false; } - if let TaskMetaStateWriteGuard::Full(mut state) = self.state_mut() { - if state.stateful { - stats.no_gc_possible += 1; - return None; + match &mut state.state_type { + TaskStateType::Done { dependencies } => { + dependencies.shrink_to_fit(); } - match &mut state.state_type { - TaskStateType::Done { dependencies } => { - dependencies.shrink_to_fit(); - } - TaskStateType::Dirty { .. } => {} - _ => { - // GC can't run in this state. We will reschedule it when the execution - // completes. - stats.no_gc_needed += 1; - return None; - } + TaskStateType::Dirty { .. } => {} + _ => { + // GC can't run in this state. We will reschedule it when the execution + // completes. + return false; } + } - // Check if the task need to be activated again - let active = if state.gc.inactive { - let active = state.aggregation_leaf.get_root_info( - &TaskAggregationContext::new(turbo_tasks, backend), - &RootInfoType::IsActive, - ); - if active { - state.gc.inactive = false; - true - } else { - false - } - } else { - true - }; - - let last_duration = state.stats.last_duration(); - let compute_duration = last_duration.into(); - - let age = to_exp_u8( - (now_relative_to_start - .saturating_sub(state.stats.last_execution_relative_to_start())) - .as_secs(), - ); - - let min_prio_that_needs_total_duration = if active { - GcPriority::EmptyCells { - total_compute_duration: to_exp_u8(last_duration.as_millis() as u64), - age: Reverse(age), - } - } else { - GcPriority::InactiveUnload { - total_compute_duration: to_exp_u8(last_duration.as_millis() as u64), - age: Reverse(age), - } - }; - - let need_total_duration = max_priority >= min_prio_that_needs_total_duration; - let has_unused_cells = state.cells.values().any(|cells| { - cells - .iter() - .any(|cell| cell.has_value() && !cell.has_dependent_tasks()) - }); - - let empty_unused_priority = if active { - GcPriority::EmptyUnusedCells { compute_duration } - } else { - GcPriority::InactiveEmptyUnusedCells { compute_duration } - }; - - if !need_total_duration { - // Fast mode, no need for total duration - - if has_unused_cells { - if empty_unused_priority <= max_priority { - // Empty unused cells - for cells in state.cells.values_mut() { - cells.shrink_to_fit(); - for cell in cells.iter_mut() { - if !cell.has_dependent_tasks() { - cells_to_drop.extend(cell.gc_content()); - } - cell.shrink_to_fit(); - } - } - stats.empty_unused_fast += 1; - return Some(GcPriority::EmptyCells { - total_compute_duration: to_exp_u8( - Duration::from(compute_duration).as_millis() as u64, - ), - age: Reverse(age), - }); - } else { - stats.priority_updated_fast += 1; - return Some(empty_unused_priority); - } - } else if active { - stats.priority_updated += 1; - return Some(GcPriority::EmptyCells { - total_compute_duration: to_exp_u8( - Duration::from(compute_duration).as_millis() as u64, - ), - age: Reverse(age), - }); - } else { - stats.priority_updated += 1; - return Some(GcPriority::InactiveUnload { - total_compute_duration: to_exp_u8( - Duration::from(compute_duration).as_millis() as u64, - ), - age: Reverse(age), - }); - } - } else { - // Slow mode, need to compute total duration - - let mut has_used_cells = false; - for cells in state.cells.values_mut() { - for cell in cells.iter_mut() { - if cell.has_value() && cell.has_dependent_tasks() { - has_used_cells = true; - for &task_id in cell.dependent_tasks() { - if included_tasks.insert(task_id) { - if let Some(duration) = task_duration_cache.get(&task_id) { - dependent_tasks_compute_duration += *duration; - } else { - missing_durations.push(task_id); - } - } - } - } - } - } - - if !active { - for &task_id in state.output.dependent_tasks() { - if included_tasks.insert(task_id) { - if let Some(duration) = task_duration_cache.get(&task_id) { - dependent_tasks_compute_duration += *duration; - } else { - missing_durations.push(task_id); - } - } - } - } - - let total_compute_duration = - max(last_duration, dependent_tasks_compute_duration); - let total_compute_duration_u8 = - to_exp_u8(total_compute_duration.as_millis() as u64); - - // When we have all information available, we can either run the GC or return a - // new GC priority. - if missing_durations.is_empty() { - let mut new_priority = GcPriority::Placeholder; - if !active { - new_priority = GcPriority::InactiveUnload { - age: Reverse(age), - total_compute_duration: total_compute_duration_u8, - }; - if new_priority <= max_priority { - // Unload task - if self.unload(state, backend, turbo_tasks) { - stats.unloaded += 1; - return None; - } else { - // unloading will fail if the task go active again - return Some(GcPriority::EmptyCells { - total_compute_duration: total_compute_duration_u8, - age: Reverse(age), - }); - } - } - } - - // always shrinking memory - state.output.dependent_tasks.shrink_to_fit(); - if active && (has_unused_cells || has_used_cells) { - new_priority = GcPriority::EmptyCells { - total_compute_duration: total_compute_duration_u8, - age: Reverse(age), - }; - if new_priority <= max_priority { - // Empty cells - let cells = take(&mut state.cells); - for cells in cells.into_values() { - for mut cell in cells { - if cell.has_value() { - cells_to_drop.extend(cell.gc_content()); - } - } - } - stats.empty_cells += 1; - return None; - } - } - - // always shrinking memory - state.cells.shrink_to_fit(); - if has_unused_cells && active { - new_priority = empty_unused_priority; - if new_priority <= max_priority { - // Empty unused cells - for cells in state.cells.values_mut() { - cells.shrink_to_fit(); - for cell in cells.iter_mut() { - if !cell.has_dependent_tasks() { - cells_to_drop.extend(cell.gc_content()); - } - cell.shrink_to_fit(); - } - } - stats.empty_unused += 1; - return Some(GcPriority::EmptyCells { - total_compute_duration: total_compute_duration_u8, - age: Reverse(age), - }); - } - } - - // Shrink memory - for cells in state.cells.values_mut() { - cells.shrink_to_fit(); - for cell in cells.iter_mut() { - cell.shrink_to_fit(); - } - } - - // Return new gc priority if any - if new_priority != GcPriority::Placeholder { - stats.priority_updated += 1; - - return Some(new_priority); - } else { - stats.no_gc_needed += 1; - - return None; - } + // shrinking memory and dropping cells + state.output.dependent_tasks.shrink_to_fit(); + state.cells.shrink_to_fit(); + for cells in state.cells.values_mut() { + cells.shrink_to_fit(); + for cell in cells.iter_mut() { + if cell.has_value() { + cells_to_drop.extend(cell.gc_content()); } + cell.shrink_to_fit(); } - } else { - // Task is already unloaded, we are done with GC for it - stats.no_gc_needed += 1; - return None; } - } + true + } else { + false + }; + + drop(cells_to_drop); + + result } - pub(crate) fn gc_compute_duration(&self) -> Duration { + pub(crate) fn gc_state(&self) -> Option { if let TaskMetaStateReadGuard::Full(state) = self.state() { - state.stats.last_duration() + Some(state.gc) } else { - Duration::ZERO + None } } + // TODO not used yet, but planned + #[allow(dead_code)] fn unload( &self, mut full_state: FullTaskWriteGuard<'_>, backend: &MemoryBackend, turbo_tasks: &dyn TurboTasksBackendApi, ) -> bool { + let mut aggregation_context = TaskAggregationContext::new(turbo_tasks, backend); let mut clear_dependencies = None; + let mut change_job = None; let TaskState { - ref mut aggregation_leaf, + ref mut aggregation_node, ref mut state_type, .. } = *full_state; @@ -2009,28 +1614,14 @@ impl Task { Done { ref mut dependencies, } => { - let mut aggregation_context = TaskAggregationContext::new(turbo_tasks, backend); - aggregation_leaf.change( - &TaskAggregationContext::new(turbo_tasks, backend), - &TaskChange { + change_job = aggregation_node.apply_change( + &aggregation_context, + TaskChange { unfinished: 1, dirty_tasks_update: vec![(self.id, 1)], ..Default::default() }, ); - if aggregation_context.take_scheduled_dirty_task(self.id) { - // Unloading is only possible for inactive tasks. - // We need to abort the unloading, so revert changes done so far. - aggregation_leaf.change( - &TaskAggregationContext::new(turbo_tasks, backend), - &TaskChange { - unfinished: -1, - dirty_tasks_update: vec![(self.id, -1)], - ..Default::default() - }, - ); - return false; - } clear_dependencies = Some(take(dependencies)); } Dirty { @@ -2040,10 +1631,7 @@ impl Task { // We want to get rid of this Event, so notify it to make sure it's empty. event.notify(usize::MAX); if !outdated_dependencies.is_empty() { - // TODO we need to find a way to handle this case without introducting a race - // condition - - return false; + clear_dependencies = Some(take(outdated_dependencies)); } } _ => { @@ -2057,17 +1645,14 @@ impl Task { let old_state = replace( &mut *state, // placeholder - TaskMetaState::Unloaded(UnloadedTaskState { - stats_type: StatsType::Essential, - }), + TaskMetaState::Unloaded(UnloadedTaskState {}), ); let TaskState { children, cells, output, collectibles, - aggregation_leaf, - stats, + mut aggregation_node, // can be dropped as it will be recomputed on next execution stateful: _, // can be dropped as it can be recomputed @@ -2078,48 +1663,42 @@ impl Task { gc: _, } = old_state.into_full().unwrap(); - let aggregation_context = TaskAggregationContext::new(turbo_tasks, backend); - // Remove all children, as they will be added again when this task is executed // again - if !children.is_empty() { - for child in children { - aggregation_leaf.remove_child(&aggregation_context, &child); - } - } + let remove_job = (!children.is_empty()) + .then(|| aggregation_node.handle_lost_edges(&aggregation_context, &self.id, children)); // Remove all collectibles, as they will be added again when this task is // executed again. - if let Some(collectibles) = collectibles.into_inner() { - aggregation_leaf.change( + let collectibles_job = if let Some(collectibles) = collectibles.into_inner() { + aggregation_node.apply_change( &aggregation_context, - &TaskChange { + TaskChange { collectibles: collectibles .into_iter() .map(|((t, r), c)| (t, r, -c)) .collect(), ..Default::default() }, - ); - } + ) + } else { + None + }; - // TODO aggregation_leaf - let unset = !aggregation_leaf.has_upper(); + // TODO aggregation_node + let unset = false; - let stats_type = match stats { - TaskStats::Essential(_) => StatsType::Essential, - TaskStats::Full(_) => StatsType::Full, - }; if unset { - *state = TaskMetaState::Unloaded(UnloadedTaskState { stats_type }); + *state = TaskMetaState::Unloaded(UnloadedTaskState {}); } else { - *state = TaskMetaState::Partial(Box::new(PartialTaskState { - aggregation_leaf, - stats_type, - })); + *state = TaskMetaState::Partial(Box::new(PartialTaskState { aggregation_node })); } drop(state); + change_job.apply(&aggregation_context); + remove_job.apply(&aggregation_context); + collectibles_job.apply(&aggregation_context); + // Notify everyone that is listening on our output or cells. // This will mark everyone as dirty and will trigger a new execution when they // become active again. @@ -2130,11 +1709,15 @@ impl Task { } output.gc_drop(turbo_tasks); - // We can clear the dependencies as we are already marked as dirty + // TODO This is a race condition, the task might be executed again while + // removing dependencies We can clear the dependencies as we are already + // marked as dirty if let Some(dependencies) = clear_dependencies { self.clear_dependencies(dependencies, backend, turbo_tasks); } + aggregation_context.apply_queued_updates(); + true } } @@ -2167,10 +1750,3 @@ impl PartialEq for Task { } impl Eq for Task {} - -pub struct TaskStatsInfo { - pub total_duration: Option, - pub last_duration: Duration, - pub executions: Option, - pub unloaded: bool, -} diff --git a/crates/turbo-tasks-memory/src/task/aggregation.rs b/crates/turbo-tasks-memory/src/task/aggregation.rs index 92749f364fd42..f790436f8bf0f 100644 --- a/crates/turbo-tasks-memory/src/task/aggregation.rs +++ b/crates/turbo-tasks-memory/src/task/aggregation.rs @@ -1,7 +1,9 @@ use std::{ - borrow::Cow, + cmp::Ordering, hash::{BuildHasher, Hash}, mem::take, + ops::{ControlFlow, Deref, DerefMut}, + sync::atomic::AtomicU32, }; use auto_hash_map::{map::Entry, AutoMap}; @@ -9,11 +11,14 @@ use nohash_hasher::BuildNoHashHasher; use parking_lot::Mutex; use turbo_tasks::{event::Event, RawVc, TaskId, TaskIdSet, TraitTypeId, TurboTasksBackendApi}; -use super::{meta_state::TaskMetaStateWriteGuard, TaskStateType}; +use super::{ + meta_state::{FullTaskWriteGuard, TaskMetaStateWriteGuard}, + TaskStateType, +}; use crate::{ - aggregation_tree::{ - aggregation_info, AggregationContext, AggregationInfoReference, AggregationItemLock, - AggregationTreeLeaf, + aggregation::{ + aggregation_data, AggregationContext, AggregationDataGuard, AggregationNode, + AggregationNodeGuard, RootQuery, }, MemoryBackend, }; @@ -36,10 +41,6 @@ impl CollectiblesInfo { } } -pub enum RootInfoType { - IsActive, -} - pub struct Aggregated { /// The number of unfinished items in the lower aggregation level. /// Unfinished means not "Done". @@ -159,14 +160,6 @@ impl<'a> TaskAggregationContext<'a> { } } - pub fn take_scheduled_dirty_task(&mut self, task: TaskId) -> bool { - let dirty_task_to_schedule = self.dirty_tasks_to_schedule.get_mut(); - dirty_task_to_schedule - .as_mut() - .map(|t| t.remove(&task)) - .unwrap_or(false) - } - pub fn apply_queued_updates(&mut self) { { let mut _span = None; @@ -191,8 +184,8 @@ impl<'a> TaskAggregationContext<'a> { } } - pub fn aggregation_info(&self, id: TaskId) -> AggregationInfoReference { - aggregation_info(self, &id) + pub fn aggregation_data(&self, id: TaskId) -> AggregationDataGuard> { + aggregation_data(self, &id) } } @@ -215,26 +208,31 @@ impl<'a> Drop for TaskAggregationContext<'a> { } impl<'a> AggregationContext for TaskAggregationContext<'a> { - type ItemLock<'l> = TaskGuard<'l> where Self: 'l; - type Info = Aggregated; - type ItemChange = TaskChange; - type ItemRef = TaskId; - type RootInfo = bool; - type RootInfoType = RootInfoType; - - fn item<'b>(&'b self, reference: &TaskId) -> Self::ItemLock<'b> { + type Guard<'l> = TaskGuard<'l> where Self: 'l; + type Data = Aggregated; + type DataChange = TaskChange; + type NodeRef = TaskId; + + fn node<'b>(&'b self, reference: &TaskId) -> Self::Guard<'b> { let task = self.backend.task(*reference); - TaskGuard { - id: *reference, - guard: task.state_mut(), - } + TaskGuard::new(*reference, task.state_mut()) + } + + fn atomic_in_progress_counter<'l>(&self, id: &'l TaskId) -> &'l AtomicU32 + where + Self: 'l, + { + &self + .backend + .task(*id) + .graph_modification_in_progress_counter } fn apply_change( &self, info: &mut Aggregated, - change: &Self::ItemChange, - ) -> Option { + change: &Self::DataChange, + ) -> Option { let mut unfinished = 0; if info.unfinished > 0 { info.unfinished += change.unfinished; @@ -249,15 +247,28 @@ impl<'a> AggregationContext for TaskAggregationContext<'a> { } } #[cfg(feature = "track_unfinished")] + let mut unfinished_tasks_update = Vec::new(); + #[cfg(feature = "track_unfinished")] for &(task, count) in change.unfinished_tasks_update.iter() { - update_count_entry(info.unfinished_tasks.entry(task), count); + match update_count_entry(info.unfinished_tasks.entry(task), count) { + (_, UpdateCountEntryChange::Removed) => unfinished_tasks_update.push((task, -1)), + (_, UpdateCountEntryChange::Inserted) => unfinished_tasks_update.push((task, 1)), + _ => {} + } } + let mut dirty_tasks_update = Vec::new(); let is_root = info.root_type.is_some(); for &(task, count) in change.dirty_tasks_update.iter() { - let value = update_count_entry(info.dirty_tasks.entry(task), count); - if is_root && value > 0 && value <= count { - let mut tasks_to_schedule = self.dirty_tasks_to_schedule.lock(); - tasks_to_schedule.get_or_insert_default().insert(task); + match update_count_entry(info.dirty_tasks.entry(task), count) { + (_, UpdateCountEntryChange::Removed) => dirty_tasks_update.push((task, -1)), + (_, UpdateCountEntryChange::Inserted) => { + if is_root { + let mut tasks_to_schedule = self.dirty_tasks_to_schedule.lock(); + tasks_to_schedule.get_or_insert_default().insert(task); + } + dirty_tasks_update.push((task, 1)) + } + _ => {} } } for &(trait_type_id, collectible, count) in change.collectibles.iter() { @@ -265,7 +276,7 @@ impl<'a> AggregationContext for TaskAggregationContext<'a> { match collectibles_info_entry { Entry::Occupied(mut e) => { let collectibles_info = e.get_mut(); - let value = update_count_entry( + let (value, _) = update_count_entry( collectibles_info.collectibles.entry(collectible), count, ); @@ -298,8 +309,8 @@ impl<'a> AggregationContext for TaskAggregationContext<'a> { let new_change = TaskChange { unfinished, #[cfg(feature = "track_unfinished")] - unfinished_tasks_update: change.unfinished_tasks_update.clone(), - dirty_tasks_update: change.dirty_tasks_update.clone(), + unfinished_tasks_update: unfinished_tasks_update, + dirty_tasks_update, collectibles: change.collectibles.clone(), }; if new_change.is_empty() { @@ -309,19 +320,23 @@ impl<'a> AggregationContext for TaskAggregationContext<'a> { } } - fn info_to_add_change(&self, info: &Aggregated) -> Option { + fn data_to_add_change(&self, data: &Aggregated) -> Option { let mut change = TaskChange::default(); - if info.unfinished > 0 { + if data.unfinished > 0 { change.unfinished = 1; } #[cfg(feature = "track_unfinished")] - for (&task, &count) in info.unfinished_tasks.iter() { - change.unfinished_tasks_update.push((task, count)); + for (&task, &count) in data.unfinished_tasks.iter() { + if count > 0 { + change.unfinished_tasks_update.push((task, 1)); + } } - for (&task, &count) in info.dirty_tasks.iter() { - change.dirty_tasks_update.push((task, count)); + for (&task, &count) in data.dirty_tasks.iter() { + if count > 0 { + change.dirty_tasks_update.push((task, 1)); + } } - for (trait_type_id, collectibles_info) in info.collectibles.iter() { + for (trait_type_id, collectibles_info) in data.collectibles.iter() { for (collectible, count) in collectibles_info.collectibles.iter() { change .collectibles @@ -335,19 +350,19 @@ impl<'a> AggregationContext for TaskAggregationContext<'a> { } } - fn info_to_remove_change(&self, info: &Aggregated) -> Option { + fn data_to_remove_change(&self, data: &Aggregated) -> Option { let mut change = TaskChange::default(); - if info.unfinished > 0 { + if data.unfinished > 0 { change.unfinished = -1; } #[cfg(feature = "track_unfinished")] - for (&task, &count) in info.unfinished_tasks.iter() { + for (&task, &count) in data.unfinished_tasks.iter() { change.unfinished_tasks_update.push((task, -count)); } - for (&task, &count) in info.dirty_tasks.iter() { + for (&task, &count) in data.dirty_tasks.iter() { change.dirty_tasks_update.push((task, -count)); } - for (trait_type_id, collectibles_info) in info.collectibles.iter() { + for (trait_type_id, collectibles_info) in data.collectibles.iter() { for (collectible, count) in collectibles_info.collectibles.iter() { change .collectibles @@ -360,71 +375,86 @@ impl<'a> AggregationContext for TaskAggregationContext<'a> { Some(change) } } +} - fn new_root_info(&self, _root_info_type: &RootInfoType) -> Self::RootInfo { - false - } +#[derive(Default)] +pub struct ActiveQuery { + active: bool, +} - fn info_to_root_info( - &self, - info: &Aggregated, - root_info_type: &RootInfoType, - ) -> Self::RootInfo { - match root_info_type { - RootInfoType::IsActive => info.root_type.is_some(), - } - } +impl RootQuery for ActiveQuery { + type Data = Aggregated; + type Result = bool; - fn merge_root_info( - &self, - root_info: &mut Self::RootInfo, - other: Self::RootInfo, - ) -> std::ops::ControlFlow<()> { - if other { - *root_info = true; - std::ops::ControlFlow::Break(()) + fn query(&mut self, data: &Self::Data) -> ControlFlow<()> { + if data.root_type.is_some() { + self.active = true; + ControlFlow::Break(()) } else { - std::ops::ControlFlow::Continue(()) + ControlFlow::Continue(()) } } + + fn result(self) -> Self::Result { + self.active + } } pub struct TaskGuard<'l> { - pub(super) id: TaskId, - pub(super) guard: TaskMetaStateWriteGuard<'l>, + id: TaskId, + guard: TaskMetaStateWriteGuard<'l>, } -impl<'l> AggregationItemLock for TaskGuard<'l> { - type Info = Aggregated; - type ItemRef = TaskId; - type ItemChange = TaskChange; - type ChildrenIter<'a> = impl Iterator> + 'a where Self: 'a; +impl<'l> TaskGuard<'l> { + pub fn new(id: TaskId, mut guard: TaskMetaStateWriteGuard<'l>) -> Self { + guard.ensure_at_least_partial(); + Self { id, guard } + } - fn leaf(&mut self) -> &mut AggregationTreeLeaf { - self.guard.ensure_at_least_partial(); - match self.guard { - TaskMetaStateWriteGuard::Full(ref mut guard) => &mut guard.aggregation_leaf, - TaskMetaStateWriteGuard::Partial(ref mut guard) => &mut guard.aggregation_leaf, - TaskMetaStateWriteGuard::Unloaded(_) => unreachable!(), + pub fn from_full(id: TaskId, guard: FullTaskWriteGuard<'l>) -> Self { + Self { + id, + guard: TaskMetaStateWriteGuard::Full(guard), } } - fn reference(&self) -> &Self::ItemRef { - &self.id + pub fn into_inner(self) -> TaskMetaStateWriteGuard<'l> { + self.guard } +} - fn number_of_children(&self) -> usize { +impl<'l> Deref for TaskGuard<'l> { + type Target = AggregationNode< + ::NodeRef, + ::Data, + >; + + fn deref(&self) -> &Self::Target { match self.guard { - TaskMetaStateWriteGuard::Full(ref guard) => match &guard.state_type { - #[cfg(feature = "lazy_remove_children")] - TaskStateType::InProgress { - outdated_children, .. - } => guard.children.len() + outdated_children.len(), - _ => guard.children.len(), - }, - TaskMetaStateWriteGuard::Partial(_) | TaskMetaStateWriteGuard::Unloaded(_) => 0, + TaskMetaStateWriteGuard::Full(ref guard) => &guard.aggregation_node, + TaskMetaStateWriteGuard::Partial(ref guard) => &guard.aggregation_node, + TaskMetaStateWriteGuard::Unloaded(_) => unreachable!(), + TaskMetaStateWriteGuard::TemporaryFiller => unreachable!(), } } +} + +impl<'l> DerefMut for TaskGuard<'l> { + fn deref_mut(&mut self) -> &mut Self::Target { + match self.guard { + TaskMetaStateWriteGuard::Full(ref mut guard) => &mut guard.aggregation_node, + TaskMetaStateWriteGuard::Partial(ref mut guard) => &mut guard.aggregation_node, + TaskMetaStateWriteGuard::Unloaded(_) => unreachable!(), + TaskMetaStateWriteGuard::TemporaryFiller => unreachable!(), + } + } +} + +impl<'l> AggregationNodeGuard for TaskGuard<'l> { + type Data = Aggregated; + type NodeRef = TaskId; + type DataChange = TaskChange; + type ChildrenIter<'a> = impl Iterator + 'a where Self: 'a; fn children(&self) -> Self::ChildrenIter<'_> { match self.guard { @@ -434,14 +464,14 @@ impl<'l> AggregationItemLock for TaskGuard<'l> { let outdated_children = match &guard.state_type { TaskStateType::InProgress { outdated_children, .. - } => Some(outdated_children.iter().map(Cow::Borrowed)), + } => Some(outdated_children.iter().copied()), _ => None, }; Some( guard .children .iter() - .map(Cow::Borrowed) + .copied() .chain(outdated_children.into_iter().flatten()), ) .into_iter() @@ -449,18 +479,17 @@ impl<'l> AggregationItemLock for TaskGuard<'l> { } #[cfg(not(feature = "lazy_remove_children"))] { - Some(guard.children.iter().map(Cow::Borrowed)) - .into_iter() - .flatten() + Some(guard.children.iter().copied()).into_iter().flatten() } } TaskMetaStateWriteGuard::Partial(_) | TaskMetaStateWriteGuard::Unloaded(_) => { None.into_iter().flatten() } + TaskMetaStateWriteGuard::TemporaryFiller => unreachable!(), } } - fn get_add_change(&self) -> Option { + fn get_add_change(&self) -> Option { match self.guard { TaskMetaStateWriteGuard::Full(ref guard) => { let mut change = TaskChange::default(); @@ -502,10 +531,11 @@ impl<'l> AggregationItemLock for TaskGuard<'l> { } } TaskMetaStateWriteGuard::Partial(_) | TaskMetaStateWriteGuard::Unloaded(_) => None, + TaskMetaStateWriteGuard::TemporaryFiller => unreachable!(), } } - fn get_remove_change(&self) -> Option { + fn get_remove_change(&self) -> Option { match self.guard { TaskMetaStateWriteGuard::Full(ref guard) => { let mut change = TaskChange::default(); @@ -547,30 +577,87 @@ impl<'l> AggregationItemLock for TaskGuard<'l> { } } TaskMetaStateWriteGuard::Partial(_) | TaskMetaStateWriteGuard::Unloaded(_) => None, + TaskMetaStateWriteGuard::TemporaryFiller => unreachable!(), + } + } + + fn get_initial_data(&self) -> Self::Data { + let mut data = Aggregated::default(); + if let Some(TaskChange { + unfinished, + #[cfg(feature = "track_unfinished")] + unfinished_tasks_update, + dirty_tasks_update, + collectibles, + }) = self.get_add_change() + { + data.unfinished = unfinished; + #[cfg(feature = "track_unfinished")] + { + data.unfinished_tasks = unfinished_tasks_update.into_iter().collect(); + } + data.dirty_tasks = dirty_tasks_update.into_iter().collect(); + data.collectibles = collectibles + .into_iter() + .map(|(trait_type_id, collectible, count)| { + ( + trait_type_id, + CollectiblesInfo { + collectibles: [(collectible, count)].iter().cloned().collect(), + dependent_tasks: TaskIdSet::default(), + }, + ) + }) + .collect(); } + data } } -pub type TaskAggregationTreeLeaf = AggregationTreeLeaf; +pub type TaskAggregationNode = AggregationNode; + +enum UpdateCountEntryChange { + Removed, + Inserted, + Updated, +} fn update_count_entry( entry: Entry<'_, K, i32, H, I>, update: i32, -) -> i32 { +) -> (i32, UpdateCountEntryChange) { match entry { Entry::Occupied(mut e) => { let value = e.get_mut(); - *value += update; - if *value == 0 { - e.remove(); - 0 + if *value < 0 { + *value += update; + match (*value).cmp(&0) { + Ordering::Less => (*value, UpdateCountEntryChange::Updated), + Ordering::Equal => { + e.remove(); + (0, UpdateCountEntryChange::Updated) + } + Ordering::Greater => (*value, UpdateCountEntryChange::Inserted), + } } else { - *value + *value += update; + match (*value).cmp(&0) { + Ordering::Less => (*value, UpdateCountEntryChange::Removed), + Ordering::Equal => { + e.remove(); + (0, UpdateCountEntryChange::Removed) + } + Ordering::Greater => (*value, UpdateCountEntryChange::Updated), + } } } Entry::Vacant(e) => { - e.insert(update); - update + if update == 0 { + (0, UpdateCountEntryChange::Updated) + } else { + e.insert(update); + (update, UpdateCountEntryChange::Inserted) + } } } } diff --git a/crates/turbo-tasks-memory/src/task/meta_state.rs b/crates/turbo-tasks-memory/src/task/meta_state.rs index 381a81e90a274..9d38c49eb6a82 100644 --- a/crates/turbo-tasks-memory/src/task/meta_state.rs +++ b/crates/turbo-tasks-memory/src/task/meta_state.rs @@ -1,10 +1,12 @@ use std::mem::replace; use parking_lot::{RwLockReadGuard, RwLockWriteGuard}; -use turbo_tasks::StatsType; use super::{PartialTaskState, Task, TaskState, UnloadedTaskState}; -use crate::map_guard::{ReadGuard, WriteGuard}; +use crate::{ + aggregation::AggregationNode, + map_guard::{ReadGuard, WriteGuard}, +}; pub(super) enum TaskMetaState { Full(Box), @@ -118,6 +120,7 @@ pub(super) enum TaskMetaStateWriteGuard<'a> { TaskMetaStateAsUnloadedMut, >, ), + TemporaryFiller, } impl<'a> From> for TaskMetaStateReadGuard<'a> { @@ -176,9 +179,7 @@ impl<'a> TaskMetaStateWriteGuard<'a> { let partial = replace( &mut *guard, // placeholder - TaskMetaState::Unloaded(UnloadedTaskState { - stats_type: StatsType::Essential, - }), + TaskMetaState::Unloaded(UnloadedTaskState {}), ) .into_partial() .unwrap(); @@ -189,9 +190,7 @@ impl<'a> TaskMetaStateWriteGuard<'a> { let unloaded = replace( &mut *guard, // placeholder - TaskMetaState::Unloaded(UnloadedTaskState { - stats_type: StatsType::Essential, - }), + TaskMetaState::Unloaded(UnloadedTaskState {}), ) .into_unloaded() .unwrap(); @@ -219,9 +218,7 @@ impl<'a> TaskMetaStateWriteGuard<'a> { let unloaded = replace( &mut *guard, // placeholder - TaskMetaState::Unloaded(UnloadedTaskState { - stats_type: StatsType::Essential, - }), + TaskMetaState::Unloaded(UnloadedTaskState {}), ) .into_unloaded() .unwrap(); @@ -247,12 +244,26 @@ impl<'a> TaskMetaStateWriteGuard<'a> { TaskMetaStateWriteGuard::Full(state) => state.into_inner(), TaskMetaStateWriteGuard::Partial(state) => state.into_inner(), TaskMetaStateWriteGuard::Unloaded(state) => state.into_inner(), + TaskMetaStateWriteGuard::TemporaryFiller => unreachable!(), } } pub(super) fn ensure_at_least_partial(&mut self) { - if let TaskMetaStateWriteGuard::Unloaded(_state) = self { - todo!() + if matches!(self, TaskMetaStateWriteGuard::Unloaded(..)) { + let TaskMetaStateWriteGuard::Unloaded(state) = + replace(self, TaskMetaStateWriteGuard::TemporaryFiller) + else { + unreachable!(); + }; + let mut state = state.into_inner(); + *state = TaskMetaState::Partial(Box::new(PartialTaskState { + aggregation_node: AggregationNode::new(), + })); + *self = TaskMetaStateWriteGuard::Partial(WriteGuard::new( + state, + TaskMetaState::as_partial, + TaskMetaState::as_partial_mut, + )); } } } diff --git a/crates/turbo-tasks-memory/src/task/stats.rs b/crates/turbo-tasks-memory/src/task/stats.rs deleted file mode 100644 index 141a18a8205a2..0000000000000 --- a/crates/turbo-tasks-memory/src/task/stats.rs +++ /dev/null @@ -1,143 +0,0 @@ -use std::time::Duration; - -use turbo_tasks::{small_duration::SmallDuration, StatsType}; - -/// Keeps track of the number of times a task has been executed, and its -/// duration. -#[derive(Debug, Clone, Eq, PartialEq)] -pub enum TaskStats { - Essential(TaskStatsEssential), - Full(Box), -} - -impl TaskStats { - /// Creates a new [`TaskStats`]. - pub fn new(stats_type: StatsType) -> Self { - match stats_type { - turbo_tasks::StatsType::Essential => Self::Essential(TaskStatsEssential::default()), - turbo_tasks::StatsType::Full => Self::Full(Box::default()), - } - } - - /// Resets the number of executions to 1 only if it was greater than 1. - pub fn reset_executions(&mut self) { - if let Self::Full(stats) = self { - if stats.executions > 1 { - stats.executions = 1; - } - } - } - - /// Increments the number of executions by 1. - pub fn increment_executions(&mut self) { - if let Self::Full(stats) = self { - stats.executions += 1; - } - } - - /// Registers a task duration. - pub fn register_execution(&mut self, duration: Duration, duration_since_start: Duration) { - match self { - Self::Full(stats) => { - stats.total_duration += duration; - stats.last_duration = duration; - } - Self::Essential(stats) => { - stats.last_duration = duration.into(); - stats.last_execution_relative_to_start = duration_since_start.into(); - } - } - } - - /// Resets stats to their default, zero-value. - pub fn reset(&mut self) { - match self { - Self::Full(stats) => { - stats.executions = 0; - stats.total_duration = Duration::ZERO; - stats.last_duration = Duration::ZERO; - } - Self::Essential(stats) => { - stats.last_duration = SmallDuration::MIN; - stats.last_execution_relative_to_start = SmallDuration::MIN; - } - } - } - - /// Returns the last duration of the task. - pub fn last_duration(&self) -> Duration { - match self { - Self::Full(stats) => stats.last_duration(), - Self::Essential(stats) => stats.last_duration(), - } - } - - /// Returns the last execution of the task relative to the start of the - /// program. - pub fn last_execution_relative_to_start(&self) -> Duration { - match self { - Self::Full(stats) => stats.last_execution_relative_to_start(), - Self::Essential(stats) => stats.last_execution_relative_to_start(), - } - } -} - -#[derive(Debug, Default, Clone, Eq, PartialEq)] -pub struct TaskStatsEssential { - /// The last duration of the task, with a precision of 10 microseconds. - last_duration: SmallDuration<10_000>, - /// The last execution of the task relative to the start of the program, - /// with a precision of 1 millisecond. - last_execution_relative_to_start: SmallDuration<1_000_000>, -} - -impl TaskStatsEssential { - /// Returns the last duration of the task. - pub fn last_duration(&self) -> Duration { - self.last_duration.into() - } - - /// Returns the last execution of the task relative to the start of the - /// program. - #[allow(dead_code)] // NOTE(alexkirsz) This will be useful for GC. - pub fn last_execution_relative_to_start(&self) -> Duration { - self.last_execution_relative_to_start.into() - } -} - -#[derive(Debug, Default, Clone, Eq, PartialEq)] -pub struct TaskStatsFull { - /// The number of times the task has been executed. - executions: u32, - /// The last duration of the task. - last_duration: Duration, - /// The total duration of the task. - total_duration: Duration, - /// The last execution of the task relative to the start of the program, - /// with a precision of 1 millisecond. - last_execution_relative_to_start: SmallDuration<1_000_000>, -} - -impl TaskStatsFull { - /// Returns the number of times the task has been executed. - pub fn executions(&self) -> u32 { - self.executions - } - - /// Returns the last duration of the task. - pub fn last_duration(&self) -> Duration { - self.last_duration - } - - /// Returns the total duration of the task. - pub fn total_duration(&self) -> Duration { - self.total_duration - } - - /// Returns the last execution of the task relative to the start of the - /// program. - #[allow(dead_code)] // NOTE(alexkirsz) This will be useful for GC. - pub fn last_execution_relative_to_start(&self) -> Duration { - self.last_execution_relative_to_start.into() - } -} diff --git a/crates/turbo-tasks-memory/src/viz/graph.rs b/crates/turbo-tasks-memory/src/viz/graph.rs deleted file mode 100644 index 6677ecaae564a..0000000000000 --- a/crates/turbo-tasks-memory/src/viz/graph.rs +++ /dev/null @@ -1,293 +0,0 @@ -use turbo_tasks::StatsType; - -use super::*; - -pub fn wrap_html(graph: &str) -> String { - format!( - r#" - - - - -turbo-tasks graph - - - - -"#, - escape_in_template_str(graph) - ) -} - -struct GlobalData<'a> { - ids: HashMap<&'a StatsTaskType, usize>, - depths: HashMap<&'a StatsTaskType, usize>, - output: String, - edges: String, -} - -impl<'a> GlobalData<'a> { - fn get_id(&mut self, ty: &'a StatsTaskType) -> usize { - get_id(ty, &mut self.ids) - } -} - -pub fn visualize_stats_tree( - root: GroupTree, - tree_ref_type: ReferenceType, - stats_type: StatsType, -) -> String { - let max_values = get_max_values(&root); - let mut depths = HashMap::new(); - compute_depths(&root, 0, &mut depths); - let mut global_data = GlobalData { - ids: HashMap::new(), - depths, - output: "digraph {\nrankdir=LR\n\n".to_string(), - edges: String::new(), - }; - visualize_stats_tree_internal( - &root, - 0, - tree_ref_type, - &max_values, - &mut global_data, - stats_type, - ); - global_data.output += &global_data.edges; - global_data.output += "\n}"; - global_data.output -} - -fn visualize_stats_tree_internal<'a>( - node: &'a GroupTree, - depth: usize, - tree_ref_type: ReferenceType, - max_values: &MaxValues, - global_data: &mut GlobalData<'a>, - stats_type: StatsType, -) { - let GroupTree { - primary, - children, - task_types, - } = node; - if let Some((ty, stats)) = primary { - let id = global_data.get_id(ty); - let label = get_task_label(ty, stats, max_values, stats_type); - writeln!( - &mut global_data.output, - "subgraph cluster_{id} {{\ncolor=lightgray;" - ) - .unwrap(); - writeln!( - &mut global_data.output, - "task_{id} [shape=plaintext, label={label}]" - ) - .unwrap(); - visualize_stats_references_internal( - id, - stats.count, - &stats.references, - depth, - tree_ref_type, - global_data, - ); - } - for (ty, stats) in task_types.iter() { - let id = global_data.get_id(ty); - let label = get_task_label(ty, stats, max_values, stats_type); - writeln!( - &mut global_data.output, - "task_{id} [shape=plaintext, label={label}]" - ) - .unwrap(); - visualize_stats_references_internal( - id, - stats.count, - &stats.references, - depth, - tree_ref_type, - global_data, - ); - } - for child in children.iter() { - visualize_stats_tree_internal( - child, - depth + 1, - tree_ref_type, - max_values, - global_data, - stats_type, - ); - } - if primary.is_some() { - global_data.output.push_str("}\n"); - } -} - -fn visualize_stats_references_internal<'a>( - source_id: usize, - source_count: usize, - references: &'a HashMap<(ReferenceType, StatsTaskType), ReferenceStats>, - depth: usize, - tree_ref_type: ReferenceType, - global_data: &mut GlobalData<'a>, -) { - let mut far_types = Vec::new(); - for ((ref_ty, ty), stats) in references.iter() { - let target_id = global_data.get_id(ty); - let is_far = global_data - .depths - .get(ty) - .map(|d| *d < depth) - .unwrap_or(false); - if ref_ty == &tree_ref_type { - let label = get_child_label(ref_ty, stats, source_count); - if is_far { - far_types.push((ty, label)); - } else { - writeln!( - &mut global_data.edges, - "task_{source_id} -> task_{target_id} [style=dashed, color=lightgray, \ - label=\"{label}\"]" - ) - .unwrap(); - } - } - } - if !far_types.is_empty() { - if far_types.len() == 1 { - let (ty, label) = far_types.first().unwrap(); - let target_id = global_data.get_id(ty); - writeln!( - &mut global_data.output, - "far_task_{source_id}_{target_id} [label=\"{ty}\", style=dashed]" - ) - .unwrap(); - writeln!( - &mut global_data.edges, - "task_{source_id} -> far_task_{source_id}_{target_id} [style=dashed, \ - color=lightgray, label=\"{label}\"]" - ) - .unwrap(); - } else { - writeln!( - &mut global_data.output, - "far_tasks_{source_id} [label=\"{}\", style=dashed]", - escape_in_template_str( - &far_types - .iter() - .map(|(ty, label)| format!("{label} {ty}")) - .collect::>() - .join("\n") - ) - ) - .unwrap(); - writeln!( - &mut global_data.edges, - "task_{source_id} -> far_tasks_{source_id} [style=dashed, color=lightgray]" - ) - .unwrap(); - } - } -} - -fn get_task_label( - ty: &StatsTaskType, - stats: &ExportedTaskStats, - max_values: &MaxValues, - stats_type: StatsType, -) -> String { - let (total_millis, total_color) = if let Some((total_duration, max_total_duration)) = - stats.total_duration.zip(max_values.total_duration) - { - let total_color = as_color(as_frac( - total_duration.as_millis(), - max_total_duration.as_millis(), - )); - let total_millis = format!("{}ms", total_duration.as_millis()); - (total_millis, total_color) - } else { - ("N/A".to_string(), "#ffffff".to_string()) - }; - - let (avg_label, avg_color) = if let Some(((executions, total_duration), max_avg_duration)) = - stats - .executions - .zip(stats.total_duration) - .zip(max_values.avg_duration) - { - let avg_color = as_color(as_frac( - total_duration.as_micros() / (executions as u128), - max_avg_duration.as_micros(), - )); - let avg = (total_duration.as_micros() as u32 / executions) as f32 / 1000.0; - (format!("avg {}ms", avg), avg_color) - } else { - ("avg N/A".to_string(), "#ffffff".to_string()) - }; - let count = as_frac(stats.count, max_values.count); - let (updates_label, updates_color) = - if let Some((executions, max_updates)) = stats.executions.zip(max_values.updates) { - let updates_color = as_color(as_frac( - executions.saturating_sub(stats.count as u32), - max_updates as u32, - )); - let updates = executions - stats.count as u32; - (format!("{}", updates), updates_color) - } else { - ("N/A".to_string(), "#ffffff".to_string()) - }; - - let full_stats_disclaimer = if stats_type.is_full() { - "".to_string() - } else { - r##" - - - Full stats collection is disabled. Pass --full-stats to enable it. - - -"## - .to_string() - }; - - format!( - "< - - - - - - - - - - - - - {} -
{}
count{}+ {}
exec{}{}
>", - total_color, - escape_html(&ty.to_string()), - as_color(count), - stats.count, - updates_color, - updates_label, - total_color, - total_millis, - avg_color, - avg_label, - full_stats_disclaimer - ) -} diff --git a/crates/turbo-tasks-memory/src/viz/mod.rs b/crates/turbo-tasks-memory/src/viz/mod.rs deleted file mode 100644 index 8656c812c4811..0000000000000 --- a/crates/turbo-tasks-memory/src/viz/mod.rs +++ /dev/null @@ -1,236 +0,0 @@ -pub mod graph; -pub mod table; - -use std::{ - cmp::max, - collections::HashMap, - fmt::{Debug, Write}, - ops::{Div, Mul}, - time::Duration, -}; - -use turbo_tasks_hash::hash_xxh3_hash64; - -use crate::stats::{ExportedTaskStats, GroupTree, ReferenceStats, ReferenceType, StatsTaskType}; - -fn escape_in_template_str(s: &str) -> String { - s.replace('\\', "\\\\") - .replace('\"', "\\\"") - .replace('\n', "\\n") -} - -fn escape_html(s: &str) -> String { - s.replace('>', ">").replace('<', "<") -} - -fn get_id<'a>(ty: &'a StatsTaskType, ids: &mut HashMap<&'a StatsTaskType, usize>) -> usize { - let len = ids.len(); - *ids.entry(ty).or_insert(len) -} - -struct MaxValues { - pub total_duration: Option, - pub total_current_duration: Duration, - pub total_update_duration: Duration, - pub avg_duration: Option, - pub max_duration: Duration, - pub count: usize, - pub unloaded_count: usize, - pub updates: Option, - /// stored as dependencies * 100 - pub dependencies: usize, - /// stored as children * 100 - pub children: usize, - pub depth: u32, -} - -fn get_max_values(node: &GroupTree) -> MaxValues { - get_max_values_internal(0, node) -} - -pub fn get_avg_dependencies_count_times_100(stats: &ExportedTaskStats) -> usize { - stats - .references - .iter() - .filter(|((ty, _), _)| *ty == ReferenceType::Dependency) - .map(|(_, ref_stats)| ref_stats.count) - .sum::() - * 100 - / stats.count -} - -pub fn get_avg_children_count_times_100(stats: &ExportedTaskStats) -> usize { - stats - .references - .iter() - .filter(|((ty, _), _)| *ty == ReferenceType::Child) - .map(|(_, ref_stats)| ref_stats.count) - .sum::() - * 100 - / stats.count -} - -fn get_max_values_internal(depth: u32, node: &GroupTree) -> MaxValues { - let mut max_total_duration = None; - let mut max_total_current_duration = Duration::ZERO; - let mut max_total_update_duration = Duration::ZERO; - let mut max_avg_duration = None; - let mut max_max_duration = Duration::ZERO; - let mut max_count = 0; - let mut max_unloaded_count = 0; - let mut max_updates = None; - let mut max_dependencies = 0; - let mut max_children = 0; - let mut max_depth = 0; - for (_, ref s) in node.task_types.iter().chain(node.primary.iter()) { - if let Some(total_duration) = s.total_duration { - max_total_duration = max_total_duration - .map(|max_total_duration| max(max_total_duration, total_duration)) - .or(Some(total_duration)); - } - max_total_current_duration = max(max_total_current_duration, s.total_current_duration); - max_total_update_duration = max(max_total_update_duration, s.total_update_duration); - if let Some((total_duration, executions)) = s.total_duration.zip(s.executions) { - if executions > 0 { - let avg_duration = total_duration / executions; - max_avg_duration = max_avg_duration - .map(|max_avg_duration| max(max_avg_duration, avg_duration)) - .or(Some(avg_duration)); - } - } - max_max_duration = max(max_max_duration, s.max_duration); - max_count = max(max_count, s.count); - max_unloaded_count = max(max_unloaded_count, s.unloaded_count); - if let Some(executions) = s.executions { - let updates = (executions as usize).saturating_sub(s.count); - max_updates = max_updates - .map(|max_updates| max(max_updates, updates)) - .or(Some(updates)); - } - max_dependencies = max(max_dependencies, get_avg_dependencies_count_times_100(s)); - max_children = max(max_children, get_avg_children_count_times_100(s)); - } - max_depth = max( - max_depth, - if node.task_types.is_empty() { - depth - } else { - depth + 1 - }, - ); - for child in node.children.iter() { - let MaxValues { - total_duration, - total_current_duration, - total_update_duration, - avg_duration, - max_duration, - count, - unloaded_count, - updates, - dependencies, - children, - depth: inner_depth, - } = get_max_values_internal(depth + 1, child); - max_total_duration = max_total_duration - .zip(total_duration) - .map(|(a, b)| max(a, b)); - max_total_current_duration = max(max_total_current_duration, total_current_duration); - max_total_update_duration = max(max_total_update_duration, total_update_duration); - max_avg_duration = max_avg_duration.zip(avg_duration).map(|(a, b)| max(a, b)); - max_max_duration = max(max_max_duration, max_duration); - max_count = max(max_count, count); - max_unloaded_count = max(max_unloaded_count, unloaded_count); - max_updates = max_updates.zip(updates).map(|(a, b)| max(a, b)); - max_dependencies = max(max_dependencies, dependencies); - max_children = max(max_children, children); - max_depth = max(max_depth, inner_depth); - } - MaxValues { - total_duration: max_total_duration, - total_current_duration: max_total_current_duration, - total_update_duration: max_total_update_duration, - avg_duration: max_avg_duration, - max_duration: max_max_duration, - count: max_count, - unloaded_count: max_unloaded_count, - updates: max_updates, - dependencies: max_dependencies, - children: max_children, - depth: max_depth, - } -} - -fn compute_depths<'a>( - node: &'a GroupTree, - depth: usize, - output: &mut HashMap<&'a StatsTaskType, usize>, -) { - if let Some((ty, _)) = &node.primary { - output.insert(ty, depth); - } - for (ty, _) in node.task_types.iter() { - output.insert(ty, depth); - } - for child in node.children.iter() { - compute_depths(child, depth + 1, output); - } -} - -fn as_frac< - T: From + TryInto + Mul + Div + PartialEq + Ord + Copy, ->( - current: T, - total: T, -) -> u8 -where - >::Error: Debug, -{ - let min: T = u8::MIN.into(); - let max: T = u8::MAX.into(); - let result = if total == min { - min - } else { - max * current / total - }; - result.clamp(min, max).try_into().unwrap() -} - -fn as_color(n: u8) -> String { - // interpolate #fff -> #ff0 -> #f00 - if n >= 64 { - format!("#ff{:0>2x}00", u8::MAX - ((n as u32 - 64) * 4 / 3) as u8) - } else { - format!("#ffff{:0>2x}", u8::MAX - n * 4) - } -} - -fn as_hash_color(value: &String) -> String { - let hash = hash_xxh3_hash64(value.as_bytes()); - format!( - "#{:0>2x}{:0>2x}{:0>2x}", - (hash & 0x7f) + 0x80, - ((hash >> 7) & 0x7f) + 0x80, - ((hash >> 14) & 0x7f) + 0x80 - ) -} - -fn as_frac_color< - T: From + TryInto + Mul + Div + PartialEq + Ord + Copy, ->( - current: T, - total: T, -) -> String -where - >::Error: Debug, -{ - as_color(as_frac(current, total)) -} - -fn get_child_label(_ty: &ReferenceType, stats: &ReferenceStats, source_count: usize) -> String { - if stats.count == source_count { - "".to_string() - } else { - format!("{}", stats.count) - } -} diff --git a/crates/turbo-tasks-memory/src/viz/table.rs b/crates/turbo-tasks-memory/src/viz/table.rs deleted file mode 100644 index a8de44354471f..0000000000000 --- a/crates/turbo-tasks-memory/src/viz/table.rs +++ /dev/null @@ -1,239 +0,0 @@ -use turbo_tasks::{util::FormatDuration, StatsType}; - -use super::*; - -pub fn wrap_html(table_html: &str) -> String { - format!( - r#" - - - - turbo-tasks table - - - - {table_html} - - -"#, - script = r#"// https://github.com/tofsjonas/sortable -document.addEventListener("click",function(b){try{var p=function(a){return v&&a.getAttribute("data-sort-alt")||a.getAttribute("data-sort")||a.innerText},q=function(a,c){a.className=a.className.replace(w,"")+c},e=function(a,c){return a.nodeName===c?a:e(a.parentNode,c)},w=/ dir-(u|d) /,v=b.shiftKey||b.altKey,f=e(b.target,"TH"),r=e(f,"TR"),g=e(r,"TABLE");if(/\bsortable\b/.test(g.className)){var h,d=r.cells;for(b=0;b String { - let max_values = get_max_values(&root); - let mut out = String::new(); - if !stats_type.is_full() { - out += r#"

Full stats collection is disabled. Run with --full-stats to enable it.

"#; - } - out += r#""#; - out += r#""#; - out += r#""#; - out += r#""#; - out += r#""#; - out += r#""#; - out += r#""#; - out += r#""#; - out += r#""#; - out += r#""#; - out += r#""#; - out += r#""#; - out += r#""#; - out += r#""#; - out += r#""#; - out += r#""#; - let mut queue = Vec::new(); - queue.push((0, None, &root)); - fn add_task( - out: &mut String, - max_values: &MaxValues, - depth: u32, - parent: Option<&(StatsTaskType, ExportedTaskStats)>, - (ty, stats): &(StatsTaskType, ExportedTaskStats), - ) -> Result<(), std::fmt::Error> { - *out += r#""#; - let name = ty.to_string(); - // name - write!( - out, - "", - as_hash_color(&name), - escape_html(&name) - )?; - // count - write!( - out, - "", - as_frac_color(stats.count, max_values.count), - stats.count - )?; - // unloaded - write!( - out, - "", - as_frac_color(stats.unloaded_count, max_values.unloaded_count), - stats.unloaded_count - )?; - // reexecutions - let (executions_label, executions_color) = - if let Some((executions, max_updates)) = stats.executions.zip(max_values.updates) { - ( - executions.saturating_sub(stats.count as u32).to_string(), - as_frac_color( - executions.saturating_sub(stats.count as u32), - max_updates as u32, - ), - ) - } else { - ("N/A".to_string(), "white".to_string()) - }; - write!( - out, - "", - executions_color, executions_label - )?; - // total duration - let (total_duration_micros, total_duration_label, total_duration_color) = - if let Some((total_duration, max_total_duration)) = - stats.total_duration.zip(max_values.total_duration) - { - ( - format!("{}", total_duration.as_micros()), - FormatDuration(total_duration).to_string(), - as_frac_color(total_duration.as_millis(), max_total_duration.as_millis()), - ) - } else { - (String::new(), "N/A".to_string(), "white".to_string()) - }; - write!( - out, - "", - total_duration_color, total_duration_micros, total_duration_label - )?; - // total current duration - write!( - out, - "", - as_frac_color( - stats.total_current_duration.as_millis(), - max_values.total_current_duration.as_millis(), - ), - stats.total_current_duration.as_micros(), - FormatDuration(stats.total_current_duration) - )?; - // total update duration - write!( - out, - "", - as_frac_color( - stats.total_update_duration.as_millis(), - max_values.total_update_duration.as_millis(), - ), - stats.total_update_duration.as_micros(), - FormatDuration(stats.total_update_duration) - )?; - // avg duration - let (avg_duration_micros, avg_duration_label, avg_duration_color) = - if let Some(((total_duration, executions), max_avg_duration)) = stats - .total_duration - .zip(stats.executions) - .zip(max_values.avg_duration) - { - ( - format!("{}", (total_duration / executions).as_micros()), - FormatDuration(total_duration / executions).to_string(), - as_frac_color( - total_duration.as_micros() / (executions as u128), - max_avg_duration.as_micros(), - ), - ) - } else { - (String::new(), "N/A".to_string(), "white".to_string()) - }; - write!( - out, - "", - avg_duration_color, avg_duration_micros, avg_duration_label - )?; - // max duration - write!( - out, - "", - as_frac_color( - stats.max_duration.as_millis(), - max_values.max_duration.as_millis(), - ), - stats.max_duration.as_micros(), - FormatDuration(stats.max_duration) - )?; - // avg dependencies - let dependencies = get_avg_dependencies_count_times_100(stats); - write!( - out, - "", - as_frac_color(dependencies, max_values.dependencies), - (dependencies as f32) / 100.0 - )?; - // avg children - let children = get_avg_children_count_times_100(stats); - write!( - out, - "", - as_frac_color(children, max_values.children), - (children as f32) / 100.0 - )?; - // depth - write!( - out, - "", - as_frac_color(depth, max_values.depth), - depth - )?; - // common parent - if let Some((ty, _)) = parent { - let name = ty.to_string(); - write!( - out, - "", - as_hash_color(&name), - escape_html(&name) - )?; - } else { - write!(out, "",)?; - } - *out += r#""#; - Ok(()) - } - while let Some((depth, parent, node)) = queue.pop() { - let GroupTree { - primary, - children, - task_types, - } = node; - if let Some(primary) = primary { - add_task(&mut out, &max_values, depth, parent, primary).unwrap(); - } - for task in task_types.iter() { - add_task(&mut out, &max_values, depth + 1, primary.as_ref(), task).unwrap(); - } - for child in children.iter() { - queue.push((depth + 1, primary.as_ref(), child)); - } - } - out += r#""#; - out += r#"
functioncountunloadedreexecutionstotal durationtotal current durationtotal update durationavg durationmax durationavg dependenciesavg childrendepthcommon parent
{}{}{}{}{}{}{}{}{}{}{}{}{}
"#; - out -} diff --git a/crates/turbo-tasks-testing/src/lib.rs b/crates/turbo-tasks-testing/src/lib.rs index a3dc1fc4023c8..da406efdfb645 100644 --- a/crates/turbo-tasks-testing/src/lib.rs +++ b/crates/turbo-tasks-testing/src/lib.rs @@ -54,7 +54,7 @@ impl TurboTasksCallApi for VcStorage { }))); i }; - let id = TaskId::from(i + 1); + let id = TaskId::from(i as u32 + 1); handle.spawn(with_turbo_tasks_for_testing(this.clone(), id, async move { let result = AssertUnwindSafe(future).catch_unwind().await; @@ -146,7 +146,7 @@ impl TurboTasksApi for VcStorage { ) -> Result> { let tasks = self.tasks.lock().unwrap(); let i = *id - 1; - let task = tasks.get(i).unwrap(); + let task = tasks.get(i as usize).unwrap(); match task { Task::Spawned(event) => Ok(Err(event.listen())), Task::Finished(result) => match result { @@ -261,7 +261,7 @@ impl VcStorage { this: weak.clone(), ..Default::default() }), - TaskId::from(usize::MAX), + TaskId::from(u32::MAX), f, ) } diff --git a/crates/turbo-tasks/Cargo.toml b/crates/turbo-tasks/Cargo.toml index 330affe279574..2b95232eff703 100644 --- a/crates/turbo-tasks/Cargo.toml +++ b/crates/turbo-tasks/Cargo.toml @@ -42,6 +42,7 @@ tokio = { workspace = true, features = ["full"] } tracing = { workspace = true } turbo-tasks-hash = { workspace = true } turbo-tasks-macros = { workspace = true } +turbo-tasks-malloc = { workspace = true } [dev-dependencies] serde_test = "1.0.157" diff --git a/crates/turbo-tasks/src/backend.rs b/crates/turbo-tasks/src/backend.rs index bb12e9af88bfd..cfd556905ba5c 100644 --- a/crates/turbo-tasks/src/backend.rs +++ b/crates/turbo-tasks/src/backend.rs @@ -7,7 +7,7 @@ use std::{ mem::take, pin::Pin, sync::Arc, - time::{Duration, Instant}, + time::Duration, }; use anyhow::{anyhow, bail, Result}; @@ -227,7 +227,7 @@ pub trait Backend: Sync + Send { &self, task: TaskId, duration: Duration, - instant: Instant, + memory_usage: usize, stateful: bool, turbo_tasks: &dyn TurboTasksBackendApi, ) -> bool; diff --git a/crates/turbo-tasks/src/capture_future.rs b/crates/turbo-tasks/src/capture_future.rs new file mode 100644 index 0000000000000..30b87aefdbb01 --- /dev/null +++ b/crates/turbo-tasks/src/capture_future.rs @@ -0,0 +1,76 @@ +use std::{ + future::Future, + pin::Pin, + sync::{Arc, Mutex}, + task::{Context, Poll}, + time::{Duration, Instant}, +}; + +use pin_project_lite::pin_project; +use tokio::{task::futures::TaskLocalFuture, task_local}; +use turbo_tasks_malloc::{AllocationInfo, TurboMalloc}; + +task_local! { + static EXTRA: Arc>; +} + +pin_project! { + pub struct CaptureFuture> { + cell: Arc>, + #[pin] + future: TaskLocalFuture>, F>, + duration: Duration, + allocations: usize, + deallocations: usize, + } +} + +impl> CaptureFuture { + pub fn new(future: F) -> Self { + let cell = Arc::new(Mutex::new((Duration::ZERO, 0, 0))); + Self { + future: EXTRA.scope(cell.clone(), future), + cell, + duration: Duration::ZERO, + allocations: 0, + deallocations: 0, + } + } +} + +pub fn add_duration(duration: Duration) { + EXTRA.with(|cell| cell.lock().unwrap().0 += duration); +} + +pub fn add_allocation_info(alloc_info: AllocationInfo) { + EXTRA.with(|cell| { + let mut guard = cell.lock().unwrap(); + guard.1 += alloc_info.allocations; + guard.2 += alloc_info.deallocations; + }); +} + +impl> Future for CaptureFuture { + type Output = (T, Duration, Instant, usize); + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let this = self.project(); + let start = Instant::now(); + let start_allocations = TurboMalloc::allocation_counters(); + let result = this.future.poll(cx); + let elapsed = start.elapsed(); + let allocations = start_allocations.until_now(); + *this.duration += elapsed; + *this.allocations += allocations.allocations; + *this.deallocations += allocations.deallocations; + match result { + Poll::Ready(r) => { + let (duration, allocations, deallocations) = *this.cell.lock().unwrap(); + let memory_usage = (*this.allocations + allocations) + .saturating_sub(*this.deallocations + deallocations); + Poll::Ready((r, *this.duration + duration, start + elapsed, memory_usage)) + } + Poll::Pending => Poll::Pending, + } + } +} diff --git a/crates/turbo-tasks/src/completion.rs b/crates/turbo-tasks/src/completion.rs index 7949de3966dd2..a49687107594b 100644 --- a/crates/turbo-tasks/src/completion.rs +++ b/crates/turbo-tasks/src/completion.rs @@ -1,4 +1,4 @@ -use crate::{self as turbo_tasks, RawVc, Vc}; +use crate::{self as turbo_tasks, RawVc, TryJoinIterExt, Vc}; /// Just an empty type, but it's never equal to itself. /// [Vc] can be used as return value instead of `()` /// to have a concrete reference that can be awaited. @@ -55,9 +55,14 @@ impl Completions { /// Merges the list of completions into one. #[turbo_tasks::function] pub async fn completed(self: Vc) -> anyhow::Result> { - for c in self.await?.iter() { - c.await?; - } + self.await? + .iter() + .map(|&c| async move { + c.await?; + Ok(()) + }) + .try_join() + .await?; Ok(Completion::new()) } } diff --git a/crates/turbo-tasks/src/id.rs b/crates/turbo-tasks/src/id.rs index 21717f41efe5c..698a787d0a756 100644 --- a/crates/turbo-tasks/src/id.rs +++ b/crates/turbo-tasks/src/id.rs @@ -2,7 +2,7 @@ use std::{ cell::RefCell, fmt::{Debug, Display}, mem::{transmute_copy, ManuallyDrop}, - num::NonZeroUsize, + num::NonZeroU32, ops::Deref, }; @@ -14,15 +14,15 @@ macro_rules! define_id { (internal $name:ident $(,$derive:ty)*) => { #[derive(Hash, Clone, Copy, PartialEq, Eq, PartialOrd, Ord $(,$derive)*)] pub struct $name { - id: NonZeroUsize, + id: NonZeroU32, } impl $name { /// # Safety /// /// The passed `id` must not be zero. - pub unsafe fn new_unchecked(id: usize) -> Self { - Self { id: unsafe { NonZeroUsize::new_unchecked(id) } } + pub unsafe fn new_unchecked(id: u32) -> Self { + Self { id: unsafe { NonZeroU32::new_unchecked(id) } } } } @@ -33,16 +33,16 @@ macro_rules! define_id { } impl Deref for $name { - type Target = usize; + type Target = u32; fn deref(&self) -> &Self::Target { unsafe { transmute_copy(&&self.id) } } } - impl From for $name { - fn from(id: usize) -> Self { - Self { id: NonZeroUsize::new(id).expect("Ids can only be created from non zero values") } + impl From for $name { + fn from(id: u32) -> Self { + Self { id: NonZeroU32::new(id).expect("Ids can only be created from non zero values") } } } @@ -136,19 +136,19 @@ make_serializable!( ); pub trait IdMapping { - fn forward(&self, id: T) -> usize; - fn backward(&self, id: usize) -> T; + fn forward(&self, id: T) -> u32; + fn backward(&self, id: u32) -> T; } impl IdMapping for &U where U: IdMapping, { - fn forward(&self, id: T) -> usize { + fn forward(&self, id: T) -> u32 { (**self).forward(id) } - fn backward(&self, id: usize) -> T { + fn backward(&self, id: u32) -> T { (**self).backward(id) } } @@ -228,7 +228,7 @@ impl<'de> Deserialize<'de> for TaskId { E: serde::de::Error, { TASK_ID_MAPPING.with(|cell| { - let id = v as usize; + let id = v as u32; let mapped_id = if let Some(mapping) = cell.borrow().as_ref() { mapping.backward(id) } else { diff --git a/crates/turbo-tasks/src/id_factory.rs b/crates/turbo-tasks/src/id_factory.rs index 5335862466742..87203ff578c26 100644 --- a/crates/turbo-tasks/src/id_factory.rs +++ b/crates/turbo-tasks/src/id_factory.rs @@ -1,28 +1,28 @@ use std::{ marker::PhantomData, ops::Deref, - sync::atomic::{AtomicUsize, Ordering}, + sync::atomic::{AtomicU32, Ordering}, }; use concurrent_queue::ConcurrentQueue; use once_cell::sync::Lazy; pub struct IdFactory { - next_id: AtomicUsize, + next_id: AtomicU32, free_ids: Lazy>, phantom_data: PhantomData, } -impl + Deref> Default for IdFactory { +impl + Deref> Default for IdFactory { fn default() -> Self { Self::new() } } -impl + Deref> IdFactory { +impl + Deref> IdFactory { pub const fn new() -> Self { Self { - next_id: AtomicUsize::new(1), + next_id: AtomicU32::new(1), free_ids: Lazy::new(|| ConcurrentQueue::unbounded()), phantom_data: PhantomData, } diff --git a/crates/turbo-tasks/src/lib.rs b/crates/turbo-tasks/src/lib.rs index a61eb78c3bc4a..93bda5364a01f 100644 --- a/crates/turbo-tasks/src/lib.rs +++ b/crates/turbo-tasks/src/lib.rs @@ -35,6 +35,7 @@ #![feature(never_type)] pub mod backend; +mod capture_future; mod collectibles; mod completion; pub mod debug; @@ -64,7 +65,6 @@ pub mod registry; pub mod small_duration; mod state; pub mod task; -mod timed_future; pub mod trace; mod trait_ref; pub mod util; @@ -89,7 +89,7 @@ pub use keyed_cell::{global_keyed_cell, keyed_cell}; pub use manager::{ dynamic_call, emit, get_invalidator, mark_finished, mark_stateful, prevent_gc, run_once, run_once_with_reason, spawn_blocking, spawn_thread, trait_call, turbo_tasks, CurrentCellRef, - Invalidator, StatsType, TaskIdProvider, TurboTasks, TurboTasksApi, TurboTasksBackendApi, + Invalidator, TaskIdProvider, TurboTasks, TurboTasksApi, TurboTasksBackendApi, TurboTasksCallApi, Unused, UpdateInfo, }; pub use native_function::NativeFunction; diff --git a/crates/turbo-tasks/src/manager.rs b/crates/turbo-tasks/src/manager.rs index a194964a7123f..2dd0691dc99e1 100644 --- a/crates/turbo-tasks/src/manager.rs +++ b/crates/turbo-tasks/src/manager.rs @@ -21,17 +21,18 @@ use nohash_hasher::BuildNoHashHasher; use serde::{de::Visitor, Deserialize, Serialize}; use tokio::{runtime::Handle, select, task_local}; use tracing::{info_span, instrument, trace_span, Instrument, Level}; +use turbo_tasks_malloc::TurboMalloc; use crate::{ backend::{Backend, CellContent, PersistentTaskType, TaskExecutionSpec, TransientTaskType}, + capture_future::{ + CaptureFuture, {self}, + }, event::{Event, EventListener}, id::{BackendJobId, FunctionId, TraitTypeId}, id_factory::IdFactory, raw_vc::{CellId, RawVc}, registry, - timed_future::{ - TimedFuture, {self}, - }, trace::TraceRawVcs, util::StaticOrArc, Completion, ConcreteTaskInput, InvalidationReason, InvalidationReasonSet, SharedReference, @@ -128,18 +129,6 @@ pub trait TurboTasksApi: TurboTasksCallApi + Sync + Send { ) -> Pin> + Send + 'static>>; } -/// The type of stats reporting. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum StatsType { - /// Only report stats essential to Turbo Tasks' operation. - Essential, - /// Full stats reporting. - /// - /// This is useful for debugging, but it has a slight memory and performance - /// impact. - Full, -} - pub trait TaskIdProvider { fn get_fresh_task_id(&self) -> Unused; fn reuse_task_id(&self, id: Unused); @@ -208,28 +197,12 @@ pub trait TurboTasksBackendApi: /// eventually call `invalidate_tasks()` on all tasks. fn schedule_notify_tasks_set(&self, tasks: &TaskIdSet); - /// Returns the stats reporting type. - fn stats_type(&self) -> StatsType; - /// Sets the stats reporting type. - fn set_stats_type(&self, stats_type: StatsType); /// Returns the duration from the start of the program to the given instant. fn program_duration_until(&self, instant: Instant) -> Duration; /// Returns a reference to the backend. fn backend(&self) -> &B; } -impl StatsType { - /// Returns `true` if the stats type is `Essential`. - pub fn is_essential(self) -> bool { - matches!(self, Self::Essential) - } - - /// Returns `true` if the stats type is `Full`. - pub fn is_full(self) -> bool { - matches!(self, Self::Full) - } -} - impl TaskIdProvider for &dyn TurboTasksBackendApi { fn get_fresh_task_id(&self) -> Unused { (*self).get_fresh_task_id() @@ -274,9 +247,6 @@ pub struct TurboTasks { event_start: Event, event_foreground: Event, event_background: Event, - // NOTE(alexkirsz) We use an atomic bool instead of a lock around `StatsType` to avoid the - // locking overhead. - enable_full_stats: AtomicBool, program_start: Instant, } @@ -327,7 +297,6 @@ impl TurboTasks { event_start: Event::new(|| "TurboTasks::event_start".to_string()), event_foreground: Event::new(|| "TurboTasks::event_foreground".to_string()), event_background: Event::new(|| "TurboTasks::event_background".to_string()), - enable_full_stats: AtomicBool::new(false), program_start: Instant::now(), }); this.backend.startup(&*this); @@ -478,8 +447,9 @@ impl TurboTasks { }; async { - let (result, duration, instant) = - TimedFuture::new(AssertUnwindSafe(future).catch_unwind()).await; + let (result, duration, _instant, memory_usage) = + CaptureFuture::new(AssertUnwindSafe(future).catch_unwind()) + .await; let result = result.map_err(|any| match any.downcast::() { Ok(owned) => Some(Cow::Owned(*owned)), @@ -491,7 +461,11 @@ impl TurboTasks { this.backend.task_execution_result(task_id, result, &*this); let stateful = this.finish_current_task_state(); this.backend.task_execution_completed( - task_id, duration, instant, stateful, &*this, + task_id, + duration, + memory_usage, + stateful, + &*this, ) } .instrument(span) @@ -1125,20 +1099,6 @@ impl TurboTasksBackendApi for TurboTasks { self.schedule(task) } - fn stats_type(&self) -> StatsType { - match self.enable_full_stats.load(Ordering::Acquire) { - true => StatsType::Full, - false => StatsType::Essential, - } - } - - fn set_stats_type(&self, stats_type: StatsType) { - match stats_type { - StatsType::Full => self.enable_full_stats.store(true, Ordering::Release), - StatsType::Essential => self.enable_full_stats.store(false, Ordering::Release), - } - } - fn program_duration_until(&self, instant: Instant) -> Duration { instant - self.program_start } @@ -1413,16 +1373,18 @@ pub fn emit(collectible: Vc) { pub async fn spawn_blocking(func: impl FnOnce() -> T + Send + 'static) -> T { let span = trace_span!("blocking operation").or_current(); - let (r, d) = tokio::task::spawn_blocking(|| { + let (result, duration, alloc_info) = tokio::task::spawn_blocking(|| { let _guard = span.entered(); let start = Instant::now(); + let start_allocations = TurboMalloc::allocation_counters(); let r = func(); - (r, start.elapsed()) + (r, start.elapsed(), start_allocations.until_now()) }) .await .unwrap(); - timed_future::add_duration(d); - r + capture_future::add_duration(duration); + capture_future::add_allocation_info(alloc_info); + result } pub fn spawn_thread(func: impl FnOnce() + Send + 'static) { diff --git a/crates/turbo-tasks/src/registry.rs b/crates/turbo-tasks/src/registry.rs index b120b99e149b8..df2f3f16a3201 100644 --- a/crates/turbo-tasks/src/registry.rs +++ b/crates/turbo-tasks/src/registry.rs @@ -30,7 +30,7 @@ static TRAIT_TYPES_BY_VALUE: Lazy> = static TRAIT_TYPES: Lazy> = Lazy::new(NoMoveVec::new); fn register_thing< - K: From + Deref + Sync + Send + Copy, + K: From + Deref + Sync + Send + Copy, V: Clone + Hash + Ord + Eq + Sync + Send + Copy, const INITIAL_CAPACITY_BITS: u32, >( @@ -45,7 +45,7 @@ fn register_thing< let new_id = id_factory.get(); // SAFETY: this is a fresh id unsafe { - store.insert(*new_id, (value, global_name)); + store.insert(*new_id as usize, (value, global_name)); } map_by_name.insert(global_name, new_id); e.insert(new_id); @@ -53,7 +53,7 @@ fn register_thing< } fn get_thing_id< - K: From + Deref + Sync + Send + Copy + Debug, + K: From + Deref + Sync + Send + Copy + Debug, V: Clone + Hash + Ord + Eq + Debug + Sync + Send + Debug, >( value: V, @@ -86,11 +86,11 @@ pub fn get_function_id_by_global_name(global_name: &str) -> Option { } pub fn get_function(id: FunctionId) -> &'static NativeFunction { - FUNCTIONS.get(*id).unwrap().0 + FUNCTIONS.get(*id as usize).unwrap().0 } pub fn get_function_global_name(id: FunctionId) -> &'static str { - FUNCTIONS.get(*id).unwrap().1 + FUNCTIONS.get(*id as usize).unwrap().1 } pub fn register_value_type(global_name: &'static str, ty: &'static ValueType) { @@ -113,11 +113,11 @@ pub fn get_value_type_id_by_global_name(global_name: &str) -> Option &'static ValueType { - VALUE_TYPES.get(*id).unwrap().0 + VALUE_TYPES.get(*id as usize).unwrap().0 } pub fn get_value_type_global_name(id: ValueTypeId) -> &'static str { - VALUE_TYPES.get(*id).unwrap().1 + VALUE_TYPES.get(*id as usize).unwrap().1 } pub fn register_trait_type(global_name: &'static str, ty: &'static TraitType) { @@ -140,9 +140,9 @@ pub fn get_trait_type_id_by_global_name(global_name: &str) -> Option &'static TraitType { - TRAIT_TYPES.get(*id).unwrap().0 + TRAIT_TYPES.get(*id as usize).unwrap().0 } pub fn get_trait_type_global_name(id: TraitTypeId) -> &'static str { - TRAIT_TYPES.get(*id).unwrap().1 + TRAIT_TYPES.get(*id as usize).unwrap().1 } diff --git a/crates/turbo-tasks/src/state.rs b/crates/turbo-tasks/src/state.rs index 072a2558729b1..d2346ba103fe1 100644 --- a/crates/turbo-tasks/src/state.rs +++ b/crates/turbo-tasks/src/state.rs @@ -54,7 +54,7 @@ impl Eq for State {} impl Serialize for State { fn serialize(&self, _serializer: S) -> Result { - // For this to work at all we need to do more. Changing the the state need to + // For this to work at all we need to do more. Changing the state need to // invalidate the serialization of the task that contains the state. So we // probably need to store the state outside of the task to be able to serialize // it independent from the creating task. diff --git a/crates/turbo-tasks/src/task/function.rs b/crates/turbo-tasks/src/task/function.rs index 1a15f24f69585..b753f468158b8 100644 --- a/crates/turbo-tasks/src/task/function.rs +++ b/crates/turbo-tasks/src/task/function.rs @@ -12,7 +12,7 @@ //! work, but they are described in this blog post: //! https://blog.logrocket.com/rust-bevy-entity-component-system/ //! -//! However, there are is an additional complication in our case: async methods +//! However, there is an additional complication in our case: async methods //! that accept a reference to the receiver as their first argument. //! //! This complication handled through our own version of the `async_trait` diff --git a/crates/turbo-tasks/src/task/task_input.rs b/crates/turbo-tasks/src/task/task_input.rs index 2b3fd67c59bf5..9d1e2ffc40ea3 100644 --- a/crates/turbo-tasks/src/task/task_input.rs +++ b/crates/turbo-tasks/src/task/task_input.rs @@ -161,26 +161,26 @@ impl TaskInput for usize { impl TaskInput for ValueTypeId { fn try_from_concrete(value: &ConcreteTaskInput) -> Result { match value { - ConcreteTaskInput::Usize(value) => Ok(ValueTypeId::from(*value)), + ConcreteTaskInput::U32(value) => Ok(ValueTypeId::from(*value)), _ => bail!("invalid task input type, expected ValueTypeId"), } } fn into_concrete(self) -> ConcreteTaskInput { - ConcreteTaskInput::Usize(*self) + ConcreteTaskInput::U32(*self) } } impl TaskInput for TaskId { fn try_from_concrete(value: &ConcreteTaskInput) -> Result { match value { - ConcreteTaskInput::Usize(value) => Ok(TaskId::from(*value)), + ConcreteTaskInput::U32(value) => Ok(TaskId::from(*value)), _ => bail!("invalid task input type, expected TaskId"), } } fn into_concrete(self) -> ConcreteTaskInput { - ConcreteTaskInput::Usize(*self) + ConcreteTaskInput::U32(*self) } } diff --git a/crates/turbo-tasks/src/timed_future.rs b/crates/turbo-tasks/src/timed_future.rs deleted file mode 100644 index 5575a86e6d1b9..0000000000000 --- a/crates/turbo-tasks/src/timed_future.rs +++ /dev/null @@ -1,58 +0,0 @@ -use std::{ - future::Future, - pin::Pin, - sync::{Arc, Mutex}, - task::{Context, Poll}, - time::{Duration, Instant}, -}; - -use pin_project_lite::pin_project; -use tokio::{task::futures::TaskLocalFuture, task_local}; - -task_local! { - static EXTRA_DURATION: Arc>; -} - -pin_project! { - pub struct TimedFuture> { - cell: Arc>, - #[pin] - future: TaskLocalFuture>, F>, - duration: Duration, - } -} - -impl> TimedFuture { - pub fn new(future: F) -> Self { - let cell = Arc::new(Mutex::new(Duration::ZERO)); - Self { - future: EXTRA_DURATION.scope(cell.clone(), future), - cell, - duration: Duration::ZERO, - } - } -} - -pub fn add_duration(duration: Duration) { - EXTRA_DURATION.with(|cell| *cell.lock().unwrap() += duration); -} - -impl> Future for TimedFuture { - type Output = (T, Duration, Instant); - - fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { - let this = self.project(); - let start = Instant::now(); - let result = this.future.poll(cx); - let elapsed = start.elapsed(); - *this.duration += elapsed; - match result { - Poll::Ready(r) => Poll::Ready(( - r, - *this.duration + *this.cell.lock().unwrap(), - start + elapsed, - )), - Poll::Pending => Poll::Pending, - } - } -} diff --git a/crates/turbopack-binding/Cargo.toml b/crates/turbopack-binding/Cargo.toml index 5b8bd9814db41..0457caf89e6af 100644 --- a/crates/turbopack-binding/Cargo.toml +++ b/crates/turbopack-binding/Cargo.toml @@ -139,6 +139,7 @@ __turbopack_ecmascript_hmr_protocol = [ "turbopack-ecmascript-hmr-protocol", ] __turbopack_trace_utils = ["__turbopack", "turbopack-trace-utils"] +__turbopack_trace_server = ["__turbopack", "turbopack-trace-server"] __turbopack_env = ["__turbopack", "turbopack-env"] __turbopack_image = ["__turbopack", "turbopack-image"] @@ -236,4 +237,5 @@ turbopack-nodejs = { optional = true, workspace = true } turbopack-static = { optional = true, workspace = true } turbopack-swc-utils = { optional = true, workspace = true } turbopack-test-utils = { optional = true, workspace = true } +turbopack-trace-server = { optional = true, workspace = true } turbopack-trace-utils = { optional = true, workspace = true } diff --git a/crates/turbopack-binding/src/lib.rs b/crates/turbopack-binding/src/lib.rs index 556d58f26ac15..4dd28f7467de2 100644 --- a/crates/turbopack-binding/src/lib.rs +++ b/crates/turbopack-binding/src/lib.rs @@ -96,6 +96,8 @@ pub mod turbopack { pub use turbopack_test_utils as test_utils; #[cfg(feature = "__turbopack_tests")] pub use turbopack_tests as tests; + #[cfg(feature = "__turbopack_trace_server")] + pub use turbopack_trace_server as trace_server; #[cfg(feature = "__turbopack_trace_utils")] pub use turbopack_trace_utils as trace_utils; } diff --git a/crates/turbopack-browser/src/chunking_context.rs b/crates/turbopack-browser/src/chunking_context.rs index 1bd07e00e8637..1827006f21e45 100644 --- a/crates/turbopack-browser/src/chunking_context.rs +++ b/crates/turbopack-browser/src/chunking_context.rs @@ -16,7 +16,7 @@ use turbopack_core::{ }; use turbopack_ecmascript::{ async_chunk::module::AsyncLoaderModule, - chunk::{EcmascriptChunk, EcmascriptChunkingContext}, + chunk::EcmascriptChunk, manifest::{chunk_asset::ManifestAsyncModule, loader_item::ManifestLoaderChunkItem}, }; use turbopack_ecmascript_runtime::RuntimeType; @@ -310,24 +310,6 @@ impl ChunkingContext for BrowserChunkingContext { Ok(Vc::cell(source_maps)) } - #[turbo_tasks::function] - async fn can_be_in_same_chunk( - &self, - asset_a: Vc>, - asset_b: Vc>, - ) -> Result> { - let parent_dir = asset_a.ident().path().parent().await?; - - let path = asset_b.ident().path().await?; - if let Some(rel_path) = parent_dir.get_path_to(&path) { - if !rel_path.starts_with("node_modules/") && !rel_path.contains("/node_modules/") { - return Ok(Vc::cell(true)); - } - } - - Ok(Vc::cell(false)) - } - #[turbo_tasks::function] async fn asset_path( &self, @@ -511,11 +493,3 @@ impl ChunkingContext for BrowserChunkingContext { }) } } - -#[turbo_tasks::value_impl] -impl EcmascriptChunkingContext for BrowserChunkingContext { - #[turbo_tasks::function] - fn has_react_refresh(&self) -> Vc { - Vc::cell(true) - } -} diff --git a/crates/turbopack-browser/src/ecmascript/runtime.rs b/crates/turbopack-browser/src/ecmascript/runtime.rs index 3f0265fc0d02f..71fcbee4c0e55 100644 --- a/crates/turbopack-browser/src/ecmascript/runtime.rs +++ b/crates/turbopack-browser/src/ecmascript/runtime.rs @@ -6,8 +6,8 @@ use turbopack_core::{ ident::AssetIdent, }; use turbopack_ecmascript::chunk::{ - EcmascriptChunk, EcmascriptChunkPlaceables, EcmascriptChunkRuntime, - EcmascriptChunkRuntimeContent, EcmascriptChunkingContext, + ChunkingContext, EcmascriptChunk, EcmascriptChunkPlaceables, EcmascriptChunkRuntime, + EcmascriptChunkRuntimeContent, }; use crate::ecmascript::content::EcmascriptDevChunkContent; @@ -16,7 +16,7 @@ use crate::ecmascript::content::EcmascriptDevChunkContent; #[turbo_tasks::value(shared)] pub(crate) struct EcmascriptDevChunkRuntime { /// The chunking context that created this runtime. - chunking_context: Vc>, + chunking_context: Vc>, /// All chunks of this chunk group need to be ready for execution to start. /// When None, it will use a chunk group created from the current chunk. chunk_group: Option>, @@ -31,7 +31,7 @@ impl EcmascriptDevChunkRuntime { /// Creates a new [`Vc`]. #[turbo_tasks::function] pub fn new( - chunking_context: Vc>, + chunking_context: Vc>, evaluated_entries: Option>, ) -> Vc { EcmascriptDevChunkRuntime { diff --git a/crates/turbopack-cli/Cargo.toml b/crates/turbopack-cli/Cargo.toml index 59eba5c7ad509..5f8904a166c95 100644 --- a/crates/turbopack-cli/Cargo.toml +++ b/crates/turbopack-cli/Cargo.toml @@ -68,6 +68,7 @@ turbopack-env = { workspace = true } turbopack-node = { workspace = true } turbopack-nodejs = { workspace = true } turbopack-resolve = { workspace = true } +turbopack-trace-server = { workspace = true } turbopack-trace-utils = { workspace = true } webbrowser = { workspace = true } diff --git a/crates/turbopack-cli/src/dev/mod.rs b/crates/turbopack-cli/src/dev/mod.rs index afcfca7a216d2..17695ec11651f 100644 --- a/crates/turbopack-cli/src/dev/mod.rs +++ b/crates/turbopack-cli/src/dev/mod.rs @@ -13,7 +13,7 @@ use anyhow::{Context, Result}; use owo_colors::OwoColorize; use turbo_tasks::{ util::{FormatBytes, FormatDuration}, - StatsType, TransientInstance, TurboTasks, TurboTasksBackendApi, UpdateInfo, Value, Vc, + TransientInstance, TurboTasks, UpdateInfo, Value, Vc, }; use turbo_tasks_fs::FileSystem; use turbo_tasks_malloc::TurboMalloc; @@ -47,7 +47,6 @@ use crate::{ }, }; -pub(crate) mod turbo_tasks_viz; pub(crate) mod web_entry_source; pub struct TurbopackDevServerBuilder { @@ -217,7 +216,6 @@ impl TurbopackDevServerBuilder { project_dir.clone(), entry_requests.clone().into(), eager_compile, - turbo_tasks.clone().into(), browserslist_query.clone(), ) }; @@ -233,7 +231,6 @@ async fn source( project_dir: String, entry_requests: TransientInstance>, eager_compile: bool, - turbo_tasks: TransientInstance>, browserslist_query: String, ) -> Result>> { let project_relative = project_dir.strip_prefix(&root_dir).unwrap(); @@ -293,7 +290,6 @@ async fn source( NodeEnv::Development.cell(), browserslist_query, ); - let viz = Vc::upcast(turbo_tasks_viz::TurboTasksSource::new(turbo_tasks.into())); let static_source = Vc::upcast(StaticAssetsContentSource::new( String::new(), project_path.join("public".to_string()), @@ -308,10 +304,7 @@ async fn source( let main_source = Vc::upcast(main_source); let source = Vc::upcast(PrefixedRouterContentSource::new( Default::default(), - vec![ - ("__turbopack__".to_string(), introspect), - ("__turbo_tasks__".to_string(), viz), - ], + vec![("__turbopack__".to_string(), introspect)], main_source, )); @@ -342,12 +335,6 @@ pub async fn start_server(args: &DevArguments) -> Result<()> { .map_or(usize::MAX, |l| l * 1024 * 1024), )); - let stats_type = match args.common.full_stats { - true => StatsType::Full, - false => StatsType::Essential, - }; - tt.set_stats_type(stats_type); - let tt_clone = tt.clone(); let mut server = TurbopackDevServerBuilder::new(tt, project_dir, root_dir) diff --git a/crates/turbopack-cli/src/dev/turbo_tasks_viz.rs b/crates/turbopack-cli/src/dev/turbo_tasks_viz.rs deleted file mode 100644 index bbd80f70b313e..0000000000000 --- a/crates/turbopack-cli/src/dev/turbo_tasks_viz.rs +++ /dev/null @@ -1,142 +0,0 @@ -use std::{sync::Arc, time::Duration}; - -use anyhow::{bail, Result}; -use mime::TEXT_HTML_UTF_8; -use turbo_tasks::{get_invalidator, TurboTasks, TurboTasksBackendApi, Value, Vc}; -use turbo_tasks_fs::File; -use turbo_tasks_memory::{ - stats::{ReferenceType, Stats}, - viz, MemoryBackend, -}; -use turbopack_core::{asset::AssetContent, version::VersionedContentExt}; -use turbopack_dev_server::source::{ - route_tree::{BaseSegment, RouteTree, RouteTrees, RouteType}, - ContentSource, ContentSourceContent, ContentSourceData, ContentSourceDataFilter, - ContentSourceDataVary, GetContentSourceContent, -}; - -#[turbo_tasks::value(serialization = "none", eq = "manual", cell = "new", into = "new")] -pub struct TurboTasksSource { - #[turbo_tasks(debug_ignore, trace_ignore)] - turbo_tasks: Arc>, -} - -impl TurboTasksSource { - pub fn new(turbo_tasks: Arc>) -> Vc { - Self::cell(TurboTasksSource { turbo_tasks }) - } -} - -const INVALIDATION_INTERVAL: Duration = Duration::from_secs(3); - -#[turbo_tasks::value_impl] -impl ContentSource for TurboTasksSource { - #[turbo_tasks::function] - fn get_routes(self: Vc) -> Vc { - Vc::::cell(vec![ - RouteTree::new_route( - vec![BaseSegment::Static("graph".to_string())], - RouteType::Exact, - Vc::upcast(self), - ), - RouteTree::new_route( - vec![BaseSegment::Static("call-graph".to_string())], - RouteType::Exact, - Vc::upcast(self), - ), - RouteTree::new_route( - vec![BaseSegment::Static("table".to_string())], - RouteType::Exact, - Vc::upcast(self), - ), - RouteTree::new_route( - vec![BaseSegment::Static("reset".to_string())], - RouteType::Exact, - Vc::upcast(self), - ), - ]) - .merge() - } -} - -#[turbo_tasks::value_impl] -impl GetContentSourceContent for TurboTasksSource { - #[turbo_tasks::function] - fn vary(&self) -> Vc { - ContentSourceDataVary { - query: Some(ContentSourceDataFilter::All), - ..Default::default() - } - .cell() - } - - #[turbo_tasks::function] - async fn get( - self: Vc, - path: String, - data: Value, - ) -> Result> { - let this = self.await?; - let tt = &this.turbo_tasks; - let invalidator = get_invalidator(); - tokio::spawn({ - async move { - tokio::time::sleep(INVALIDATION_INTERVAL).await; - invalidator.invalidate(); - } - }); - let html = match path.as_str() { - "graph" => { - let mut stats = Stats::new(); - let b = tt.backend(); - b.with_all_cached_tasks(|task| { - stats.add_id(b, task); - }); - let tree = stats.treeify(ReferenceType::Dependency); - let graph = viz::graph::visualize_stats_tree( - tree, - ReferenceType::Dependency, - tt.stats_type(), - ); - viz::graph::wrap_html(&graph) - } - "call-graph" => { - let mut stats = Stats::new(); - let b = tt.backend(); - b.with_all_cached_tasks(|task| { - stats.add_id(b, task); - }); - let tree = stats.treeify(ReferenceType::Child); - let graph = - viz::graph::visualize_stats_tree(tree, ReferenceType::Child, tt.stats_type()); - viz::graph::wrap_html(&graph) - } - "table" => { - let Some(query) = &data.query else { - bail!("Missing query"); - }; - let mut stats = Stats::new(); - let b = tt.backend(); - let include_unloaded = query.contains_key("unloaded"); - b.with_all_cached_tasks(|task| { - stats.add_id_conditional(b, task, |_, info| include_unloaded || !info.unloaded); - }); - let tree = stats.treeify(ReferenceType::Dependency); - let table = viz::table::create_table(tree, tt.stats_type()); - viz::table::wrap_html(&table) - } - "reset" => { - let b = tt.backend(); - b.with_all_cached_tasks(|task| { - b.with_task(task, |task| task.reset_stats()); - }); - "Done".to_string() - } - _ => bail!("Unknown path: {}", path), - }; - Ok(ContentSourceContent::static_content( - AssetContent::file(File::from(html).with_content_type(TEXT_HTML_UTF_8).into()) - .versioned(), - )) - } -} diff --git a/crates/turbopack-core/src/chunk/chunking_context.rs b/crates/turbopack-core/src/chunk/chunking_context.rs index edc7b29eba950..132995a7a8a4b 100644 --- a/crates/turbopack-core/src/chunk/chunking_context.rs +++ b/crates/turbopack-core/src/chunk/chunking_context.rs @@ -9,7 +9,6 @@ use crate::{ chunk::{ChunkItem, ModuleId}, environment::Environment, ident::AssetIdent, - module::Module, output::{OutputAsset, OutputAssets}, }; @@ -62,12 +61,6 @@ pub trait ChunkingContext { /// Reference Source Map Assets for chunks fn reference_chunk_source_maps(self: Vc, chunk: Vc>) -> Vc; - fn can_be_in_same_chunk( - self: Vc, - asset_a: Vc>, - asset_b: Vc>, - ) -> Vc; - /// Returns a URL (relative or absolute, depending on the asset prefix) to /// the static asset based on its `ident`. fn asset_url(self: Vc, ident: Vc) -> Result>; diff --git a/crates/turbopack-core/src/lib.rs b/crates/turbopack-core/src/lib.rs index 56b79a88c1c76..bf26add21ce58 100644 --- a/crates/turbopack-core/src/lib.rs +++ b/crates/turbopack-core/src/lib.rs @@ -46,7 +46,7 @@ pub mod virtual_fs { } pub const PROJECT_FILESYSTEM_NAME: &str = "project"; -pub const SOURCE_MAP_ROOT_NAME: &str = "turbopack"; +pub const SOURCE_MAP_PREFIX: &str = "turbopack://"; #[doc(hidden)] pub mod __private { diff --git a/crates/turbopack-core/src/raw_output.rs b/crates/turbopack-core/src/raw_output.rs index 870da2bcaa0bf..b79ab79465f5b 100644 --- a/crates/turbopack-core/src/raw_output.rs +++ b/crates/turbopack-core/src/raw_output.rs @@ -1,4 +1,5 @@ use turbo_tasks::Vc; +use turbo_tasks_fs::FileSystemPath; use crate::{ asset::{Asset, AssetContent}, @@ -11,6 +12,7 @@ use crate::{ /// This module has no references to other modules. #[turbo_tasks::value] pub struct RawOutput { + path: Vc, source: Vc>, } @@ -18,7 +20,7 @@ pub struct RawOutput { impl OutputAsset for RawOutput { #[turbo_tasks::function] fn ident(&self) -> Vc { - self.source.ident() + AssetIdent::from_path(self.path) } } @@ -33,7 +35,7 @@ impl Asset for RawOutput { #[turbo_tasks::value_impl] impl RawOutput { #[turbo_tasks::function] - pub fn new(source: Vc>) -> Vc { - RawOutput { source }.cell() + pub fn new(path: Vc, source: Vc>) -> Vc { + RawOutput { path, source }.cell() } } diff --git a/crates/turbopack-core/src/reference_type.rs b/crates/turbopack-core/src/reference_type.rs index d8adea7770510..57a0a6722bcd2 100644 --- a/crates/turbopack-core/src/reference_type.rs +++ b/crates/turbopack-core/src/reference_type.rs @@ -33,11 +33,18 @@ pub enum CommonJsReferenceSubType { Undefined, } +#[turbo_tasks::value(serialization = "auto_for_input")] +#[derive(Debug, Clone, PartialOrd, Ord, Hash)] +pub enum ImportWithType { + Json, +} + #[turbo_tasks::value(serialization = "auto_for_input")] #[derive(Debug, Default, Clone, PartialOrd, Ord, Hash)] pub enum EcmaScriptModulesReferenceSubType { ImportPart(Vc), Import, + ImportWithType(ImportWithType), DynamicImport, Custom(u8), #[default] diff --git a/crates/turbopack-core/src/source_map/mod.rs b/crates/turbopack-core/src/source_map/mod.rs index db41d7e920a02..86c751187aa7c 100644 --- a/crates/turbopack-core/src/source_map/mod.rs +++ b/crates/turbopack-core/src/source_map/mod.rs @@ -14,7 +14,7 @@ use turbo_tasks_fs::{ FileContent, FileSystemPath, }; -use crate::{source_pos::SourcePos, SOURCE_MAP_ROOT_NAME}; +use crate::{source_pos::SourcePos, SOURCE_MAP_PREFIX}; pub(crate) mod source_map_asset; @@ -398,7 +398,7 @@ impl SourceMap { Ok( if let Some(path) = *origin.parent().try_join(source_request.to_string()).await? { let path_str = path.to_string().await?; - let source = format!("/{SOURCE_MAP_ROOT_NAME}/{}", path_str); + let source = format!("{SOURCE_MAP_PREFIX}{}", path_str); let source_content = if let Some(source_content) = source_content { source_content } else if let FileContent::Content(file) = &*path.read().await? { @@ -416,7 +416,7 @@ impl SourceMap { .replace_all(&source_request, |s: ®ex::Captures<'_>| { s[0].replace('.', "_") }); - let source = format!("/{SOURCE_MAP_ROOT_NAME}/{}/{}", origin_str, source); + let source = format!("{SOURCE_MAP_PREFIX}{}/{}", origin_str, source); let source_content = source_content.unwrap_or_else(|| { format!( "unable to access {source_request} in {origin_str} (it's leaving the \ diff --git a/crates/turbopack-css/src/module_asset.rs b/crates/turbopack-css/src/module_asset.rs index 2830f8e38b551..6905f14ceb199 100644 --- a/crates/turbopack-css/src/module_asset.rs +++ b/crates/turbopack-css/src/module_asset.rs @@ -23,7 +23,7 @@ use turbopack_core::{ use turbopack_ecmascript::{ chunk::{ EcmascriptChunkItem, EcmascriptChunkItemContent, EcmascriptChunkPlaceable, - EcmascriptChunkType, EcmascriptChunkingContext, EcmascriptExports, + EcmascriptChunkType, EcmascriptExports, }, utils::StringifyJs, ParseResultSourceMap, @@ -108,7 +108,7 @@ impl Asset for ModuleCssAsset { /// A CSS class that is exported from a CSS module. /// /// See [`ModuleCssClasses`] for more information. -#[turbo_tasks::value(transparent)] +#[turbo_tasks::value] #[derive(Debug, Clone)] enum ModuleCssClass { Local { @@ -237,12 +237,6 @@ impl ChunkableModule for ModuleCssAsset { self: Vc, chunking_context: Vc>, ) -> Result>> { - let chunking_context = - Vc::try_resolve_downcast::>(chunking_context) - .await? - .context( - "chunking context must impl EcmascriptChunkingContext to use ModuleCssAsset", - )?; Ok(Vc::upcast( ModuleChunkItem { chunking_context, @@ -277,7 +271,7 @@ impl ResolveOrigin for ModuleCssAsset { #[turbo_tasks::value] struct ModuleChunkItem { module: Vc, - chunking_context: Vc>, + chunking_context: Vc>, } #[turbo_tasks::value_impl] @@ -313,7 +307,7 @@ impl ChunkItem for ModuleChunkItem { #[turbo_tasks::value_impl] impl EcmascriptChunkItem for ModuleChunkItem { #[turbo_tasks::function] - fn chunking_context(&self) -> Vc> { + fn chunking_context(&self) -> Vc> { self.chunking_context } diff --git a/crates/turbopack-css/src/parse.rs b/crates/turbopack-css/src/parse.rs index 1c7ddbf463020..c1efd0ea8bc12 100644 --- a/crates/turbopack-css/src/parse.rs +++ b/crates/turbopack-css/src/parse.rs @@ -1,5 +1,5 @@ use swc_core::common::{source_map::SourceMapGenConfig, FileName}; -use turbopack_core::SOURCE_MAP_ROOT_NAME; +use turbopack_core::SOURCE_MAP_PREFIX; /// A config to generate a source map which includes the source content of every /// source file. SWC doesn't inline sources content by default when generating a @@ -9,7 +9,7 @@ pub struct InlineSourcesContentConfig {} impl SourceMapGenConfig for InlineSourcesContentConfig { fn file_name_to_source(&self, f: &FileName) -> String { match f { - FileName::Custom(s) => format!("/{SOURCE_MAP_ROOT_NAME}/{s}"), + FileName::Custom(s) => format!("{SOURCE_MAP_PREFIX}{s}"), _ => f.to_string(), } } diff --git a/crates/turbopack-css/src/process.rs b/crates/turbopack-css/src/process.rs index 23a0135703338..4b1531a0a01ca 100644 --- a/crates/turbopack-css/src/process.rs +++ b/crates/turbopack-css/src/process.rs @@ -1,17 +1,16 @@ use std::{ - collections::HashMap, + collections::{HashMap, HashSet}, sync::{Arc, RwLock}, }; use anyhow::{bail, Context, Result}; -use indexmap::IndexMap; +use indexmap::{IndexMap, IndexSet}; use lightningcss::{ css_modules::{CssModuleExport, CssModuleExports, CssModuleReference, Pattern, Segment}, dependencies::{Dependency, ImportDependency, Location, SourceRange}, stylesheet::{ParserOptions, PrinterOptions, StyleSheet, ToCssResult}, targets::{Features, Targets}, values::url::Url, - visit_types, visitor::Visit, }; use once_cell::sync::Lazy; @@ -48,7 +47,7 @@ use turbopack_core::{ source::Source, source_map::{GenerateSourceMap, OptionSourceMap}, source_pos::SourcePos, - SOURCE_MAP_ROOT_NAME, + SOURCE_MAP_PREFIX, }; use turbopack_swc_utils::emitter::IssueEmitter; @@ -572,8 +571,9 @@ async fn process_content( ) { Ok(mut ss) => { if matches!(ty, CssModuleAssetType::Module) { - let mut validator = CssValidator { errors: Vec::new() }; + let mut validator = CssModuleValidator::default(); ss.visit(&mut validator).unwrap(); + validator.validate_done(); for err in validator.errors { err.report(source, fs_path_vc); @@ -676,8 +676,9 @@ async fn process_content( } if matches!(ty, CssModuleAssetType::Module) { - let mut validator = CssValidator { errors: vec![] }; + let mut validator = CssModuleValidator::default(); ss.visit_with(&mut validator); + validator.validate_done(); for err in validator.errors { err.report(source, fs_path_vc); @@ -731,14 +732,29 @@ async fn process_content( /// ``` /// /// is wrong for a css module because it doesn't have a class name. -struct CssValidator { +#[derive(Default)] +struct CssModuleValidator { errors: Vec, + used_grid_areas: IndexSet, + used_grid_templates: HashSet, +} +impl CssModuleValidator { + fn validate_done(&mut self) { + for grid_area in &self.used_grid_areas { + if !self.used_grid_templates.contains(grid_area) { + self.errors.push(CssError::UnknownGridAreaInModules { + name: grid_area.to_string(), + }); + } + } + } } #[derive(Debug, PartialEq, Eq)] enum CssError { SwcSelectorInModuleNotPure { span: Span }, LightningCssSelectorInModuleNotPure { selector: String }, + UnknownGridAreaInModules { name: String }, } impl CssError { @@ -766,6 +782,18 @@ impl CssError { .cell() .emit(); } + + CssError::UnknownGridAreaInModules { name } => { + ParsingIssue { + file, + msg: Vc::cell(format!( + "Cannot find grid-template-areas with name '{name}'" + )), + source: Vc::cell(None), + } + .cell() + .emit(); + } } } } @@ -774,7 +802,7 @@ const CSS_MODULE_ERROR: &str = "Selector is not pure (pure selectors must contain at least one local class or id)"; /// We only vist top-level selectors. -impl swc_core::css::visit::Visit for CssValidator { +impl swc_core::css::visit::Visit for CssModuleValidator { fn visit_complex_selector(&mut self, n: &ComplexSelector) { fn is_complex_not_pure(sel: &ComplexSelector) -> bool { sel.children.iter().all(|sel| match sel { @@ -878,11 +906,73 @@ impl swc_core::css::visit::Visit for CssValidator { } /// We only vist top-level selectors. -impl lightningcss::visitor::Visitor<'_> for CssValidator { +impl lightningcss::visitor::Visitor<'_> for CssModuleValidator { type Error = (); fn visit_types(&self) -> lightningcss::visitor::VisitTypes { - visit_types!(SELECTORS) + lightningcss::visitor::VisitTypes::all() + } + + fn visit_property( + &mut self, + property: &mut lightningcss::properties::Property, + ) -> Result<(), Self::Error> { + match property { + lightningcss::properties::Property::GridArea(p) => { + for line in [&p.row_start, &p.row_end, &p.column_start, &p.column_end] { + if let lightningcss::properties::grid::GridLine::Area { name } = line { + self.used_grid_areas.insert(name.to_string()); + } + } + } + + lightningcss::properties::Property::GridColumn(p) => { + for line in [&p.start, &p.end] { + if let lightningcss::properties::grid::GridLine::Area { name } = line { + self.used_grid_areas.insert(name.to_string()); + } + } + } + + lightningcss::properties::Property::GridRow(p) => { + for line in [&p.start, &p.end] { + if let lightningcss::properties::grid::GridLine::Area { name } = line { + self.used_grid_areas.insert(name.to_string()); + } + } + } + + lightningcss::properties::Property::GridRowStart(p) + | lightningcss::properties::Property::GridRowEnd(p) + | lightningcss::properties::Property::GridColumnStart(p) + | lightningcss::properties::Property::GridColumnEnd(p) => { + if let lightningcss::properties::grid::GridLine::Area { name } = p { + self.used_grid_areas.insert(name.to_string()); + } + } + + lightningcss::properties::Property::GridTemplateAreas( + lightningcss::properties::grid::GridTemplateAreas::Areas { areas, .. }, + ) => { + for area in areas.iter().flatten() { + self.used_grid_templates.insert(area.clone()); + } + } + + lightningcss::properties::Property::GridTemplate(p) => { + if let lightningcss::properties::grid::GridTemplateAreas::Areas { areas, .. } = + &mut p.areas + { + for area in areas.iter().flatten() { + self.used_grid_templates.insert(area.clone()); + } + } + } + + _ => {} + } + + Ok(()) } fn visit_selector( @@ -977,7 +1067,7 @@ impl GenerateSourceMap for ParseCssResultSourceMap { let mut builder = SourceMapBuilder::new(None); for src in source_map.get_sources() { - builder.add_source(&format!("/{SOURCE_MAP_ROOT_NAME}/{src}")); + builder.add_source(&format!("{SOURCE_MAP_PREFIX}{src}")); } for (idx, content) in source_map.get_sources_content().iter().enumerate() { @@ -1128,7 +1218,7 @@ mod tests { css::{ast::Stylesheet, parser::parser::ParserConfig, visit::VisitWith}, }; - use super::{CssError, CssValidator}; + use super::{CssError, CssModuleValidator}; fn lint_lightningcss(code: &str) -> Vec { let mut ss = StyleSheet::parse( @@ -1143,8 +1233,9 @@ mod tests { ) .unwrap(); - let mut validator = CssValidator { errors: Vec::new() }; + let mut validator = CssModuleValidator::default(); ss.visit(&mut validator).unwrap(); + validator.validate_done(); validator.errors } @@ -1165,8 +1256,9 @@ mod tests { ) .unwrap(); - let mut validator = CssValidator { errors: Vec::new() }; + let mut validator = CssModuleValidator::default(); ss.visit_with(&mut validator); + validator.validate_done(); validator.errors } @@ -1183,6 +1275,11 @@ mod tests { assert_ne!(lint_swc(code), vec![], "swc: {code}"); } + #[track_caller] + fn assert_lint_failure_only_lightning_css(code: &str) { + assert_ne!(lint_lightningcss(code), vec![], "lightningcss: {code}"); + } + #[test] fn css_module_pure_lint() { assert_lint_success( @@ -1305,4 +1402,99 @@ mod tests { }", ); } + + #[test] + fn css_module_grid_lint() { + assert_lint_success( + r#" + .item1 { + grid-area: myArea; + } + .grid-container { + display: grid; + grid-template-areas: "myArea myArea"; + } + "#, + ); + + assert_lint_failure_only_lightning_css( + r#" + .item1 { + grid-area: my; + } + .grid-container { + display: grid; + grid-template-areas: "myArea myArea"; + } + "#, + ); + + assert_lint_failure_only_lightning_css( + r#" + .item1 { + grid-row-start: my; + } + .grid-container { + display: grid; + grid-template-areas: "myArea myArea"; + } + "#, + ); + assert_lint_failure_only_lightning_css( + r#" + .item1 { + grid-row-end: my; + } + .grid-container { + display: grid; + grid-template-areas: "myArea myArea"; + } + "#, + ); + assert_lint_failure_only_lightning_css( + r#" + .item1 { + grid-column-start: my; + } + .grid-container { + display: grid; + grid-template-areas: "myArea myArea"; + } + "#, + ); + assert_lint_failure_only_lightning_css( + r#" + .item1 { + grid-column-end: my; + } + .grid-container { + display: grid; + grid-template-areas: "myArea myArea"; + } + "#, + ); + + assert_lint_success( + r#" + .item1 { + grid-area: my; + } + .grid-container { + display: grid; + grid-template: "my" "my"; + } + "#, + ); + assert_lint_failure_only_lightning_css( + r#" + .item1 { + grid-area: my; + } + .grid-container { + display: grid; + grid-template: "myArea" "myArea" + } + "#, + ); + } } diff --git a/crates/turbopack-ecmascript-plugins/src/transform/directives/server_to_client_proxy.rs b/crates/turbopack-ecmascript-plugins/src/transform/directives/server_to_client_proxy.rs index 1415759e5a783..e9b55df950940 100644 --- a/crates/turbopack-ecmascript-plugins/src/transform/directives/server_to_client_proxy.rs +++ b/crates/turbopack-ecmascript-plugins/src/transform/directives/server_to_client_proxy.rs @@ -2,28 +2,22 @@ use swc_core::{ common::DUMMY_SP, ecma::{ ast::{ - Expr, ExprStmt, Ident, ImportDecl, ImportSpecifier, ImportStarAsSpecifier, - KeyValueProp, Lit, Module, ModuleDecl, ModuleItem, ObjectLit, Program, Prop, PropName, - PropOrSpread, Stmt, Str, + ImportDecl, ImportSpecifier, ImportStarAsSpecifier, Module, ModuleDecl, ModuleItem, + Program, }, utils::private_ident, }, quote, }; -use turbopack_ecmascript::TURBOPACK_HELPER; +use turbopack_ecmascript::{ + annotations::{with_clause, ANNOTATION_TRANSITION}, + TURBOPACK_HELPER, +}; pub fn create_proxy_module(transition_name: &str, target_import: &str) -> Program { let ident = private_ident!("clientProxy"); Program::Module(Module { body: vec![ - ModuleItem::Stmt(Stmt::Expr(ExprStmt { - expr: Box::new(Expr::Lit(Lit::Str(Str { - value: format!("TURBOPACK {{ transition: {transition_name} }}").into(), - raw: None, - span: DUMMY_SP, - }))), - span: DUMMY_SP, - })), ModuleItem::ModuleDecl(ModuleDecl::Import(ImportDecl { specifiers: vec![ImportSpecifier::Namespace(ImportStarAsSpecifier { local: ident.clone(), @@ -31,13 +25,10 @@ pub fn create_proxy_module(transition_name: &str, target_import: &str) -> Progra })], src: Box::new(target_import.into()), type_only: false, - with: Some(Box::new(ObjectLit { - span: DUMMY_SP, - props: vec![PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp { - key: PropName::Ident(Ident::new(TURBOPACK_HELPER.into(), DUMMY_SP)), - value: Box::new(Expr::Lit(true.into())), - })))], - })), + with: Some(with_clause(&[ + (TURBOPACK_HELPER.as_str(), "true"), + (ANNOTATION_TRANSITION, transition_name), + ])), span: DUMMY_SP, phase: Default::default(), })), diff --git a/crates/turbopack-ecmascript-plugins/src/transform/swc_ecma_transform_plugins.rs b/crates/turbopack-ecmascript-plugins/src/transform/swc_ecma_transform_plugins.rs index d7aa68e969446..e75b328267dc0 100644 --- a/crates/turbopack-ecmascript-plugins/src/transform/swc_ecma_transform_plugins.rs +++ b/crates/turbopack-ecmascript-plugins/src/transform/swc_ecma_transform_plugins.rs @@ -11,13 +11,7 @@ use turbopack_ecmascript::{CustomTransformer, TransformContext}; /// Internally this contains a `CompiledPluginModuleBytes`, which points to the /// compiled, serialized wasmer::Module instead of raw file bytes to reduce the /// cost of the compilation. -#[turbo_tasks::value( - transparent, - serialization = "none", - eq = "manual", - into = "new", - cell = "new" -)] +#[turbo_tasks::value(serialization = "none", eq = "manual", into = "new", cell = "new")] pub struct SwcPluginModule( #[turbo_tasks(trace_ignore)] #[cfg(feature = "swc_ecma_transform_plugin")] diff --git a/crates/turbopack-ecmascript/src/analyzer/imports.rs b/crates/turbopack-ecmascript/src/analyzer/imports.rs index 215cc053aa576..faa84ebbcccee 100644 --- a/crates/turbopack-ecmascript/src/analyzer/imports.rs +++ b/crates/turbopack-ecmascript/src/analyzer/imports.rs @@ -1,4 +1,4 @@ -use std::{collections::BTreeMap, fmt::Display, mem::take}; +use std::{collections::BTreeMap, fmt::Display}; use indexmap::{IndexMap, IndexSet}; use once_cell::sync::Lazy; @@ -14,43 +14,76 @@ use turbo_tasks::Vc; use turbopack_core::{issue::IssueSource, source::Source}; use super::{JsValue, ModuleValue}; -use crate::utils::unparen; #[turbo_tasks::value(serialization = "auto_for_input")] #[derive(Default, Debug, Clone, Hash, PartialOrd, Ord)] pub struct ImportAnnotations { // TODO store this in more structured way #[turbo_tasks(trace_ignore)] - map: BTreeMap>, + map: BTreeMap, } -/// Enables a specified transtion for the annotated import -static ANNOTATION_TRANSITION: Lazy = Lazy::new(|| "transition".into()); +/// Enables a specified transition for the annotated import +static ANNOTATION_TRANSITION: Lazy = + Lazy::new(|| crate::annotations::ANNOTATION_TRANSITION.into()); /// Changes the chunking type for the annotated import -static ANNOTATION_CHUNKING_TYPE: Lazy = Lazy::new(|| "chunking-type".into()); +static ANNOTATION_CHUNKING_TYPE: Lazy = + Lazy::new(|| crate::annotations::ANNOTATION_CHUNKING_TYPE.into()); + +/// Changes the type of the resolved module (only "json" is supported currently) +static ATTRIBUTE_MODULE_TYPE: Lazy = Lazy::new(|| "type".into()); impl ImportAnnotations { - fn insert(&mut self, key: JsWord, value: Option) { - self.map.insert(key, value); - } + pub fn parse(with: Option<&ObjectLit>) -> ImportAnnotations { + let Some(with) = with else { + return ImportAnnotations::default(); + }; + + let mut map = BTreeMap::new(); + + // The `with` clause is way more restrictive than `ObjectLit`, it only allows + // string -> value and value can only be a string. + // We just ignore everything else here till the SWC ast is more restrictive. + for (key, value) in with.props.iter().filter_map(|prop| { + let kv = prop.as_prop()?.as_key_value()?; - fn clear(&mut self) { - self.map.clear(); + let Lit::Str(str) = kv.value.as_lit()? else { + return None; + }; + + Some((&kv.key, str)) + }) { + let key = match key { + PropName::Ident(ident) => ident.sym.as_str(), + PropName::Str(str) => str.value.as_str(), + // the rest are invalid, ignore for now till SWC ast is correct + _ => continue, + }; + + map.insert(key.into(), value.value.as_str().into()); + } + + ImportAnnotations { map } } /// Returns the content on the transition annotation pub fn transition(&self) -> Option<&str> { - self.map - .get(&ANNOTATION_TRANSITION) - .and_then(|w| w.as_ref().map(|w| &**w)) + self.get(&ANNOTATION_TRANSITION) } /// Returns the content on the chunking-type annotation pub fn chunking_type(&self) -> Option<&str> { - self.map - .get(&ANNOTATION_CHUNKING_TYPE) - .and_then(|w| w.as_ref().map(|w| &**w)) + self.get(&ANNOTATION_CHUNKING_TYPE) + } + + /// Returns the content on the type attribute + pub fn module_type(&self) -> Option<&str> { + self.get(&ATTRIBUTE_MODULE_TYPE) + } + + pub fn get(&self, key: &JsWord) -> Option<&str> { + self.map.get(key).map(|w| w.as_str()) } } @@ -58,20 +91,12 @@ impl Display for ImportAnnotations { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let mut it = self.map.iter(); if let Some((k, v)) = it.next() { - if let Some(v) = v { - write!(f, "{{ {k}: {v}")? - } else { - write!(f, "{{ {k}")? - } + write!(f, "{{ {k}: {v}")? } else { return f.write_str("{}"); }; for (k, v) in it { - if let Some(v) = v { - write!(f, "; {k}: {v}")? - } else { - write!(f, "; {k}")? - } + write!(f, ", {k}: {v}")? } f.write_str(" }") } @@ -172,7 +197,6 @@ impl ImportMap { m.visit_with(&mut Analyzer { data: &mut data, - current_annotations: ImportAnnotations::default(), source, }); @@ -182,7 +206,6 @@ impl ImportMap { struct Analyzer<'a> { data: &'a mut ImportMap, - current_annotations: ImportAnnotations, source: Option>>, } @@ -222,42 +245,9 @@ fn to_word(name: &ModuleExportName) -> JsWord { } impl Visit for Analyzer<'_> { - fn visit_module_item(&mut self, n: &ModuleItem) { - if let ModuleItem::Stmt(Stmt::Expr(ExprStmt { expr, .. })) = n { - if let Expr::Lit(Lit::Str(s)) = unparen(expr) { - if s.value.starts_with("TURBOPACK") { - let value = &*s.value; - let value = value["TURBOPACK".len()..].trim(); - if !value.starts_with('{') || !value.ends_with('}') { - // TODO report issue - } else { - value[1..value.len() - 1] - .trim() - .split(';') - .map(|p| p.trim()) - .filter(|p| !p.is_empty()) - .for_each(|part| { - if let Some(colon) = part.find(':') { - self.current_annotations.insert( - part[..colon].trim_end().into(), - Some(part[colon + 1..].trim_start().into()), - ); - } else { - self.current_annotations.insert(part.into(), None); - } - }) - } - n.visit_children_with(self); - return; - } - } - } - n.visit_children_with(self); - self.current_annotations.clear(); - } - fn visit_import_decl(&mut self, import: &ImportDecl) { - let annotations = take(&mut self.current_annotations); + let annotations = ImportAnnotations::parse(import.with.as_deref()); + self.ensure_reference( import.span, import.src.value.clone(), @@ -295,7 +285,8 @@ impl Visit for Analyzer<'_> { fn visit_export_all(&mut self, export: &ExportAll) { self.data.has_exports = true; - let annotations = take(&mut self.current_annotations); + let annotations = ImportAnnotations::parse(export.with.as_deref()); + self.ensure_reference( export.span, export.src.value.clone(), @@ -313,53 +304,52 @@ impl Visit for Analyzer<'_> { fn visit_named_export(&mut self, export: &NamedExport) { self.data.has_exports = true; - if let Some(ref src) = export.src { - let annotations = take(&mut self.current_annotations); - self.ensure_reference( - export.span, - src.value.clone(), - ImportedSymbol::ModuleEvaluation, - annotations.clone(), - ); + let Some(ref src) = export.src else { + return; + }; - for spec in export.specifiers.iter() { - let symbol = get_import_symbol_from_export(spec); - - let i = self.ensure_reference( - export.span, - src.value.clone(), - symbol, - annotations.clone(), - ); - - match spec { - ExportSpecifier::Namespace(n) => { - self.data.reexports.push(( - i, - Reexport::Namespace { - exported: to_word(&n.name), - }, - )); - } - ExportSpecifier::Default(d) => { - self.data.reexports.push(( - i, - Reexport::Named { - imported: js_word!("default"), - exported: d.exported.sym.clone(), - }, - )); - } - ExportSpecifier::Named(n) => { - self.data.reexports.push(( - i, - Reexport::Named { - imported: to_word(&n.orig), - exported: to_word(n.exported.as_ref().unwrap_or(&n.orig)), - }, - )); - } + let annotations = ImportAnnotations::parse(export.with.as_deref()); + + self.ensure_reference( + export.span, + src.value.clone(), + ImportedSymbol::ModuleEvaluation, + annotations.clone(), + ); + + for spec in export.specifiers.iter() { + let symbol = get_import_symbol_from_export(spec); + + let i = + self.ensure_reference(export.span, src.value.clone(), symbol, annotations.clone()); + + match spec { + ExportSpecifier::Namespace(n) => { + self.data.reexports.push(( + i, + Reexport::Namespace { + exported: to_word(&n.name), + }, + )); + } + ExportSpecifier::Default(d) => { + self.data.reexports.push(( + i, + Reexport::Named { + imported: js_word!("default"), + exported: d.exported.sym.clone(), + }, + )); + } + ExportSpecifier::Named(n) => { + self.data.reexports.push(( + i, + Reexport::Named { + imported: to_word(&n.orig), + exported: to_word(n.exported.as_ref().unwrap_or(&n.orig)), + }, + )); } } } diff --git a/crates/turbopack-ecmascript/src/analyzer/mod.rs b/crates/turbopack-ecmascript/src/analyzer/mod.rs index 75c9d416e234a..dbd26db7b8f5a 100644 --- a/crates/turbopack-ecmascript/src/analyzer/mod.rs +++ b/crates/turbopack-ecmascript/src/analyzer/mod.rs @@ -370,7 +370,7 @@ pub enum JsValue { /// A constant primitive value. Constant(ConstantValue), /// An constant URL object. - Url(Url), + Url(Box), /// Some kind of well-known object /// (must not be an array, otherwise Array.concat needs to be changed) WellKnownObject(WellKnownObjectKind), diff --git a/crates/turbopack-ecmascript/src/analyzer/well_known.rs b/crates/turbopack-ecmascript/src/analyzer/well_known.rs index 9bf6061829a3a..04bd40eb43563 100644 --- a/crates/turbopack-ecmascript/src/analyzer/well_known.rs +++ b/crates/turbopack-ecmascript/src/analyzer/well_known.rs @@ -478,6 +478,7 @@ pub fn path_to_file_url(args: Vec) -> JsValue { if args.len() == 1 { if let Some(path) = args[0].as_str() { Url::from_file_path(path) + .map(Box::new) .map(JsValue::Url) .unwrap_or_else(|_| { JsValue::unknown( diff --git a/crates/turbopack-ecmascript/src/annotations.rs b/crates/turbopack-ecmascript/src/annotations.rs new file mode 100644 index 0000000000000..d6c2ba6847ea5 --- /dev/null +++ b/crates/turbopack-ecmascript/src/annotations.rs @@ -0,0 +1,34 @@ +use swc_core::{ + common::DUMMY_SP, + ecma::ast::{Expr, KeyValueProp, ObjectLit, Prop, PropName, PropOrSpread}, +}; + +/// Changes the chunking type for the annotated import +pub const ANNOTATION_CHUNKING_TYPE: &str = "turbopack-chunking-type"; + +/// Enables a specified transition for the annotated import +pub const ANNOTATION_TRANSITION: &str = "turbopack-transition"; + +pub fn with_chunking_type(chunking_type: &str) -> Box { + with_clause(&[(ANNOTATION_CHUNKING_TYPE, chunking_type)]) +} + +pub fn with_transition(transition_name: &str) -> Box { + with_clause(&[(ANNOTATION_TRANSITION, transition_name)]) +} + +pub fn with_clause<'a>( + entries: impl IntoIterator, +) -> Box { + Box::new(ObjectLit { + span: DUMMY_SP, + props: entries.into_iter().map(|(k, v)| with_prop(k, v)).collect(), + }) +} + +fn with_prop(key: &str, value: &str) -> PropOrSpread { + PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp { + key: PropName::Str(key.into()), + value: Box::new(Expr::Lit(value.into())), + }))) +} diff --git a/crates/turbopack-ecmascript/src/async_chunk/chunk_item.rs b/crates/turbopack-ecmascript/src/async_chunk/chunk_item.rs index ac882009bcbe3..71d0a4f699361 100644 --- a/crates/turbopack-ecmascript/src/async_chunk/chunk_item.rs +++ b/crates/turbopack-ecmascript/src/async_chunk/chunk_item.rs @@ -16,7 +16,7 @@ use crate::{ async_chunk::module::AsyncLoaderModule, chunk::{ data::EcmascriptChunkData, EcmascriptChunkItem, EcmascriptChunkItemContent, - EcmascriptChunkPlaceable, EcmascriptChunkType, EcmascriptChunkingContext, + EcmascriptChunkPlaceable, EcmascriptChunkType, }, utils::StringifyJs, }; @@ -24,7 +24,7 @@ use crate::{ #[turbo_tasks::value(shared)] pub struct AsyncLoaderChunkItem { pub module: Vc, - pub chunking_context: Vc>, + pub chunking_context: Vc>, } #[turbo_tasks::value_impl] @@ -67,7 +67,7 @@ impl AsyncLoaderChunkItem { #[turbo_tasks::value_impl] impl EcmascriptChunkItem for AsyncLoaderChunkItem { #[turbo_tasks::function] - fn chunking_context(&self) -> Vc> { + fn chunking_context(&self) -> Vc> { self.chunking_context } diff --git a/crates/turbopack-ecmascript/src/async_chunk/module.rs b/crates/turbopack-ecmascript/src/async_chunk/module.rs index 83b9ab8196393..5f2e9977a0761 100644 --- a/crates/turbopack-ecmascript/src/async_chunk/module.rs +++ b/crates/turbopack-ecmascript/src/async_chunk/module.rs @@ -1,4 +1,4 @@ -use anyhow::{Context, Result}; +use anyhow::Result; use turbo_tasks::{Value, Vc}; use turbopack_core::{ asset::{Asset, AssetContent}, @@ -8,7 +8,7 @@ use turbopack_core::{ reference::{ModuleReferences, SingleModuleReference}, }; -use crate::{async_chunk::chunk_item::AsyncLoaderChunkItem, EcmascriptChunkingContext}; +use crate::async_chunk::chunk_item::AsyncLoaderChunkItem; #[turbo_tasks::function] fn modifier() -> Vc { @@ -20,7 +20,7 @@ fn modifier() -> Vc { #[turbo_tasks::value] pub struct AsyncLoaderModule { pub inner: Vc>, - pub chunking_context: Vc>, + pub chunking_context: Vc>, pub availability_info: AvailabilityInfo, } @@ -29,7 +29,7 @@ impl AsyncLoaderModule { #[turbo_tasks::function] pub fn new( module: Vc>, - chunking_context: Vc>, + chunking_context: Vc>, availability_info: Value, ) -> Vc { Self::cell(AsyncLoaderModule { @@ -81,12 +81,6 @@ impl ChunkableModule for AsyncLoaderModule { self: Vc, chunking_context: Vc>, ) -> Result>> { - let chunking_context = - Vc::try_resolve_downcast::>(chunking_context) - .await? - .context( - "chunking context must impl EcmascriptChunkingContext to use AsyncLoaderModule", - )?; Ok(Vc::upcast( AsyncLoaderChunkItem { chunking_context, diff --git a/crates/turbopack-ecmascript/src/chunk/chunk_type.rs b/crates/turbopack-ecmascript/src/chunk/chunk_type.rs index cdebbb66ebe0d..5c5f0e4056370 100644 --- a/crates/turbopack-ecmascript/src/chunk/chunk_type.rs +++ b/crates/turbopack-ecmascript/src/chunk/chunk_type.rs @@ -7,9 +7,7 @@ use turbopack_core::{ output::OutputAssets, }; -use super::{ - EcmascriptChunk, EcmascriptChunkContent, EcmascriptChunkItem, EcmascriptChunkingContext, -}; +use super::{EcmascriptChunk, EcmascriptChunkContent, EcmascriptChunkItem}; #[derive(Default)] #[turbo_tasks::value] @@ -33,8 +31,7 @@ impl ChunkType for EcmascriptChunkType { referenced_output_assets: Vc, ) -> Result>> { let Some(chunking_context) = - Vc::try_resolve_downcast::>(chunking_context) - .await? + Vc::try_resolve_downcast::>(chunking_context).await? else { bail!("Ecmascript chunking context not found"); }; diff --git a/crates/turbopack-ecmascript/src/chunk/context.rs b/crates/turbopack-ecmascript/src/chunk/context.rs deleted file mode 100644 index d558e1d701ce2..0000000000000 --- a/crates/turbopack-ecmascript/src/chunk/context.rs +++ /dev/null @@ -1,13 +0,0 @@ -use turbo_tasks::Vc; -use turbopack_core::chunk::ChunkingContext; - -/// [`EcmascriptChunkingContext`] must be implemented by [`ChunkingContext`] -/// implementors that want to operate on [`EcmascriptChunk`]s. -#[turbo_tasks::value_trait] -pub trait EcmascriptChunkingContext: ChunkingContext { - /// Whether chunk items generated by this chunking context should include - /// the `__turbopack_refresh__` argument. - fn has_react_refresh(self: Vc) -> Vc { - Vc::cell(false) - } -} diff --git a/crates/turbopack-ecmascript/src/chunk/item.rs b/crates/turbopack-ecmascript/src/chunk/item.rs index 0ff76d099be0a..672d164fd7639 100644 --- a/crates/turbopack-ecmascript/src/chunk/item.rs +++ b/crates/turbopack-ecmascript/src/chunk/item.rs @@ -12,11 +12,10 @@ use turbopack_core::{ source_map::GenerateSourceMap, }; -use super::EcmascriptChunkingContext; use crate::{ references::async_module::{AsyncModuleOptions, OptionAsyncModuleOptions}, utils::FormatIter, - EcmascriptModuleContent, + EcmascriptModuleContent, EcmascriptOptions, }; #[turbo_tasks::value(shared)] @@ -33,10 +32,11 @@ impl EcmascriptChunkItemContent { #[turbo_tasks::function] pub async fn new( content: Vc, - chunking_context: Vc>, + chunking_context: Vc>, + options: Vc, async_module_options: Vc, ) -> Result> { - let refresh = *chunking_context.has_react_refresh().await?; + let refresh = options.await?.refresh; let externals = *chunking_context .environment() .supports_commonjs_externals() @@ -197,7 +197,7 @@ pub trait EcmascriptChunkItem: ChunkItem { ) -> Vc { self.content() } - fn chunking_context(self: Vc) -> Vc>; + fn chunking_context(self: Vc) -> Vc>; /// Specifies which availablility information the chunk item needs for code /// generation diff --git a/crates/turbopack-ecmascript/src/chunk/mod.rs b/crates/turbopack-ecmascript/src/chunk/mod.rs index f85cf92b2de5d..ca5be5b1fda28 100644 --- a/crates/turbopack-ecmascript/src/chunk/mod.rs +++ b/crates/turbopack-ecmascript/src/chunk/mod.rs @@ -1,6 +1,5 @@ pub(crate) mod chunk_type; pub(crate) mod content; -pub(crate) mod context; pub(crate) mod data; pub(crate) mod item; pub(crate) mod placeable; @@ -26,7 +25,6 @@ use turbopack_core::{ pub use self::{ chunk_type::EcmascriptChunkType, content::EcmascriptChunkContent, - context::EcmascriptChunkingContext, data::EcmascriptChunkData, item::{ EcmascriptChunkItem, EcmascriptChunkItemContent, EcmascriptChunkItemExt, @@ -37,7 +35,7 @@ pub use self::{ #[turbo_tasks::value] pub struct EcmascriptChunk { - pub chunking_context: Vc>, + pub chunking_context: Vc>, pub content: Vc, } @@ -48,7 +46,7 @@ pub struct EcmascriptChunks(Vec>); impl EcmascriptChunk { #[turbo_tasks::function] pub async fn new( - chunking_context: Vc>, + chunking_context: Vc>, content: Vc, ) -> Result> { Ok(EcmascriptChunk { diff --git a/crates/turbopack-ecmascript/src/chunk_group_files_asset.rs b/crates/turbopack-ecmascript/src/chunk_group_files_asset.rs index c49e3318955e0..bc0904272529f 100644 --- a/crates/turbopack-ecmascript/src/chunk_group_files_asset.rs +++ b/crates/turbopack-ecmascript/src/chunk_group_files_asset.rs @@ -1,4 +1,4 @@ -use anyhow::{Context, Result}; +use anyhow::Result; use indexmap::IndexSet; use turbo_tasks::{TryJoinIterExt, Value, ValueToString, Vc}; use turbo_tasks_fs::{File, FileSystemPath}; @@ -23,7 +23,7 @@ use turbopack_core::{ use crate::{ chunk::{ EcmascriptChunkItem, EcmascriptChunkItemContent, EcmascriptChunkPlaceable, - EcmascriptChunkType, EcmascriptChunkingContext, EcmascriptExports, + EcmascriptChunkType, EcmascriptExports, }, utils::StringifyJs, EcmascriptModuleAsset, @@ -96,13 +96,6 @@ impl ChunkableModule for ChunkGroupFilesAsset { chunking_context: Vc>, ) -> Result>> { let this = self.await?; - let chunking_context = - Vc::try_resolve_downcast::>(chunking_context) - .await? - .context( - "chunking context must impl EcmascriptChunkingContext to use \ - ChunkGroupFilesAsset", - )?; Ok(Vc::upcast( ChunkGroupFilesChunkItem { chunking_context, @@ -124,7 +117,7 @@ impl EcmascriptChunkPlaceable for ChunkGroupFilesAsset { #[turbo_tasks::value] struct ChunkGroupFilesChunkItem { - chunking_context: Vc>, + chunking_context: Vc>, client_root: Vc, inner: Vc, } @@ -158,7 +151,7 @@ impl ChunkGroupFilesChunkItem { #[turbo_tasks::value_impl] impl EcmascriptChunkItem for ChunkGroupFilesChunkItem { #[turbo_tasks::function] - fn chunking_context(&self) -> Vc> { + fn chunking_context(&self) -> Vc> { self.chunking_context } diff --git a/crates/turbopack-ecmascript/src/code_gen.rs b/crates/turbopack-ecmascript/src/code_gen.rs index b5140ce16ed0a..f6fbac3fd42b3 100644 --- a/crates/turbopack-ecmascript/src/code_gen.rs +++ b/crates/turbopack-ecmascript/src/code_gen.rs @@ -1,9 +1,7 @@ use serde::{Deserialize, Serialize}; use swc_core::ecma::visit::{AstParentKind, VisitMut}; use turbo_tasks::{debug::ValueDebugFormat, trace::TraceRawVcs, Vc}; -use turbopack_core::chunk::AsyncModuleInfo; - -use crate::chunk::EcmascriptChunkingContext; +use turbopack_core::chunk::{AsyncModuleInfo, ChunkingContext}; /// impl of code generation inferred from a ModuleReference. /// This is rust only and can't be implemented by non-rust plugins. @@ -28,7 +26,7 @@ pub trait VisitorFactory: Send + Sync { pub trait CodeGenerateable { fn code_generation( self: Vc, - chunking_context: Vc>, + chunking_context: Vc>, ) -> Vc; } @@ -36,7 +34,7 @@ pub trait CodeGenerateable { pub trait CodeGenerateableWithAsyncModuleInfo { fn code_generation( self: Vc, - chunking_context: Vc>, + chunking_context: Vc>, async_module_info: Option>, ) -> Vc; } diff --git a/crates/turbopack-ecmascript/src/lib.rs b/crates/turbopack-ecmascript/src/lib.rs index 23dc8fa0fcac5..1c3ae077d7522 100644 --- a/crates/turbopack-ecmascript/src/lib.rs +++ b/crates/turbopack-ecmascript/src/lib.rs @@ -8,6 +8,7 @@ #![recursion_limit = "256"] pub mod analyzer; +pub mod annotations; pub mod async_chunk; pub mod chunk; pub mod chunk_group_files_asset; @@ -32,8 +33,8 @@ pub mod webpack; use std::fmt::{Display, Formatter}; -use anyhow::{Context, Result}; -use chunk::{EcmascriptChunkItem, EcmascriptChunkingContext}; +use anyhow::Result; +use chunk::EcmascriptChunkItem; use code_gen::CodeGenerateable; pub use parse::ParseResultSourceMap; use parse::{parse, ParseResult}; @@ -119,9 +120,10 @@ pub enum TreeShakingMode { ReexportsOnly, } -#[turbo_tasks::value(serialization = "auto_for_input")] +#[turbo_tasks::value(shared, serialization = "auto_for_input")] #[derive(PartialOrd, Ord, Hash, Debug, Default, Copy, Clone)] pub struct EcmascriptOptions { + pub refresh: bool, /// variant of tree shaking to use pub tree_shaking_mode: Option, /// module is forced to a specific type (happens e. g. for .cjs and .mjs) @@ -196,7 +198,7 @@ pub struct EcmascriptModuleAssetBuilder { asset_context: Vc>, ty: EcmascriptModuleAssetType, transforms: Vc, - options: EcmascriptOptions, + options: Vc, compile_time_info: Vc, inner_assets: Option>, } @@ -219,7 +221,7 @@ impl EcmascriptModuleAssetBuilder { self.asset_context, Value::new(self.ty), self.transforms, - Value::new(self.options), + self.options, self.compile_time_info, inner_assets, ) @@ -229,16 +231,16 @@ impl EcmascriptModuleAssetBuilder { self.asset_context, Value::new(self.ty), self.transforms, - Value::new(self.options), + self.options, self.compile_time_info, ) } } - pub fn build_part(self, part: Vc) -> Vc { - let import_externals = self.options.import_externals; + pub async fn build_part(self, part: Vc) -> Result> { + let import_externals = self.options.await?.import_externals; let base = self.build(); - EcmascriptModulePartAsset::new(base, part, import_externals) + Ok(EcmascriptModulePartAsset::new(base, part, import_externals)) } } @@ -248,7 +250,7 @@ pub struct EcmascriptModuleAsset { pub asset_context: Vc>, pub ty: EcmascriptModuleAssetType, pub transforms: Vc, - pub options: EcmascriptOptions, + pub options: Vc, pub compile_time_info: Vc, pub inner_assets: Option>, #[turbo_tasks(debug_ignore)] @@ -269,7 +271,7 @@ impl EcmascriptModuleAsset { source: Vc>, asset_context: Vc>, transforms: Vc, - options: EcmascriptOptions, + options: Vc, compile_time_info: Vc, ) -> EcmascriptModuleAssetBuilder { EcmascriptModuleAssetBuilder { @@ -321,7 +323,7 @@ impl EcmascriptModuleAsset { asset_context: Vc>, ty: Value, transforms: Vc, - options: Value, + options: Vc, compile_time_info: Vc, ) -> Vc { Self::cell(EcmascriptModuleAsset { @@ -329,7 +331,7 @@ impl EcmascriptModuleAsset { asset_context, ty: ty.into_value(), transforms, - options: options.into_value(), + options, compile_time_info, inner_assets: None, last_successful_analysis: Default::default(), @@ -342,7 +344,7 @@ impl EcmascriptModuleAsset { asset_context: Vc>, ty: Value, transforms: Vc, - options: Value, + options: Vc, compile_time_info: Vc, inner_assets: Vc, ) -> Vc { @@ -351,7 +353,7 @@ impl EcmascriptModuleAsset { asset_context, ty: ty.into_value(), transforms, - options: options.into_value(), + options, compile_time_info, inner_assets: Some(inner_assets), last_successful_analysis: Default::default(), @@ -368,6 +370,11 @@ impl EcmascriptModuleAsset { analyse_ecmascript_module(self, None) } + #[turbo_tasks::function] + pub async fn options(self: Vc) -> Result> { + Ok(self.await?.options) + } + #[turbo_tasks::function] pub async fn failsafe_analyze(self: Vc) -> Result> { let this = self.await?; @@ -432,7 +439,7 @@ impl EcmascriptModuleAsset { pub(crate) async fn determine_module_type(self: Vc) -> Result> { let this = self.await?; - match this.options.specified_module_type { + match this.options.await?.specified_module_type { SpecifiedModuleType::EcmaScript => { return Ok(ModuleTypeResult::new(SpecifiedModuleType::EcmaScript)) } @@ -489,14 +496,14 @@ impl EcmascriptModuleAsset { Ok(EcmascriptModuleContent::new_without_analysis( parsed, self.ident(), - this.options.specified_module_type, + this.options.await?.specified_module_type, )) } #[turbo_tasks::function] pub async fn module_content( self: Vc, - chunking_context: Vc>, + chunking_context: Vc>, async_module_info: Option>, ) -> Result> { let this = self.await?; @@ -568,13 +575,6 @@ impl ChunkableModule for EcmascriptModuleAsset { self: Vc, chunking_context: Vc>, ) -> Result>> { - let chunking_context = - Vc::try_resolve_downcast::>(chunking_context) - .await? - .context( - "chunking context must impl EcmascriptChunkingContext to use \ - EcmascriptModuleAsset", - )?; Ok(Vc::upcast(ModuleChunkItem::cell(ModuleChunkItem { module: self, chunking_context, @@ -627,7 +627,7 @@ impl ResolveOrigin for EcmascriptModuleAsset { #[turbo_tasks::value] struct ModuleChunkItem { module: Vc, - chunking_context: Vc>, + chunking_context: Vc>, } #[turbo_tasks::value_impl] @@ -672,7 +672,7 @@ impl ChunkItem for ModuleChunkItem { #[turbo_tasks::value_impl] impl EcmascriptChunkItem for ModuleChunkItem { #[turbo_tasks::function] - fn chunking_context(&self) -> Vc> { + fn chunking_context(&self) -> Vc> { self.chunking_context } @@ -705,6 +705,7 @@ impl EcmascriptChunkItem for ModuleChunkItem { Ok(EcmascriptChunkItemContent::new( content, this.chunking_context, + this.module.options(), async_module_options, )) } @@ -716,6 +717,7 @@ pub struct EcmascriptModuleContent { pub inner_code: Rope, pub source_map: Option>>, pub is_esm: bool, + // pub refresh: bool, } #[turbo_tasks::value_impl] @@ -726,7 +728,7 @@ impl EcmascriptModuleContent { parsed: Vc, ident: Vc, specified_module_type: SpecifiedModuleType, - chunking_context: Vc>, + chunking_context: Vc>, references: Vc, code_generation: Vc, async_module: Vc, diff --git a/crates/turbopack-ecmascript/src/manifest/chunk_asset.rs b/crates/turbopack-ecmascript/src/manifest/chunk_asset.rs index 14190a2eed435..14138f4fae58b 100644 --- a/crates/turbopack-ecmascript/src/manifest/chunk_asset.rs +++ b/crates/turbopack-ecmascript/src/manifest/chunk_asset.rs @@ -1,4 +1,4 @@ -use anyhow::{Context, Result}; +use anyhow::Result; use turbo_tasks::{Value, Vc}; use turbopack_core::{ asset::{Asset, AssetContent}, @@ -12,7 +12,7 @@ use turbopack_core::{ }; use super::chunk_item::ManifestChunkItem; -use crate::chunk::{EcmascriptChunkPlaceable, EcmascriptChunkingContext, EcmascriptExports}; +use crate::chunk::{EcmascriptChunkPlaceable, EcmascriptExports}; #[turbo_tasks::function] fn modifier() -> Vc { @@ -32,7 +32,7 @@ fn modifier() -> Vc { #[turbo_tasks::value(shared)] pub struct ManifestAsyncModule { pub inner: Vc>, - pub chunking_context: Vc>, + pub chunking_context: Vc>, pub availability_info: AvailabilityInfo, } @@ -41,7 +41,7 @@ impl ManifestAsyncModule { #[turbo_tasks::function] pub fn new( module: Vc>, - chunking_context: Vc>, + chunking_context: Vc>, availability_info: Value, ) -> Vc { Self::cell(ManifestAsyncModule { @@ -143,13 +143,6 @@ impl ChunkableModule for ManifestAsyncModule { self: Vc, chunking_context: Vc>, ) -> Result>> { - let chunking_context = - Vc::try_resolve_downcast::>(chunking_context) - .await? - .context( - "chunking context must impl EcmascriptChunkingContext to use \ - ManifestChunkAsset", - )?; Ok(Vc::upcast( ManifestChunkItem { chunking_context, diff --git a/crates/turbopack-ecmascript/src/manifest/chunk_item.rs b/crates/turbopack-ecmascript/src/manifest/chunk_item.rs index add3d26446688..f636df1fe729a 100644 --- a/crates/turbopack-ecmascript/src/manifest/chunk_item.rs +++ b/crates/turbopack-ecmascript/src/manifest/chunk_item.rs @@ -12,7 +12,7 @@ use super::chunk_asset::ManifestAsyncModule; use crate::{ chunk::{ data::EcmascriptChunkData, EcmascriptChunkItem, EcmascriptChunkItemContent, - EcmascriptChunkType, EcmascriptChunkingContext, + EcmascriptChunkType, }, utils::StringifyJs, }; @@ -22,7 +22,7 @@ use crate::{ /// __turbopack_import__ the actual module that was dynamically imported. #[turbo_tasks::value(shared)] pub(super) struct ManifestChunkItem { - pub chunking_context: Vc>, + pub chunking_context: Vc>, pub manifest: Vc, } @@ -41,7 +41,7 @@ impl ManifestChunkItem { #[turbo_tasks::value_impl] impl EcmascriptChunkItem for ManifestChunkItem { #[turbo_tasks::function] - fn chunking_context(&self) -> Vc> { + fn chunking_context(&self) -> Vc> { self.chunking_context } diff --git a/crates/turbopack-ecmascript/src/manifest/loader_item.rs b/crates/turbopack-ecmascript/src/manifest/loader_item.rs index 42604673c236d..4044f64485b59 100644 --- a/crates/turbopack-ecmascript/src/manifest/loader_item.rs +++ b/crates/turbopack-ecmascript/src/manifest/loader_item.rs @@ -16,7 +16,7 @@ use super::chunk_asset::ManifestAsyncModule; use crate::{ chunk::{ data::EcmascriptChunkData, EcmascriptChunkItem, EcmascriptChunkItemContent, - EcmascriptChunkPlaceable, EcmascriptChunkType, EcmascriptChunkingContext, + EcmascriptChunkPlaceable, EcmascriptChunkType, }, utils::StringifyJs, }; @@ -145,7 +145,7 @@ impl ChunkItem for ManifestLoaderChunkItem { #[turbo_tasks::value_impl] impl EcmascriptChunkItem for ManifestLoaderChunkItem { #[turbo_tasks::function] - async fn chunking_context(&self) -> Result>> { + async fn chunking_context(&self) -> Result>> { Ok(self.manifest.await?.chunking_context) } diff --git a/crates/turbopack-ecmascript/src/parse.rs b/crates/turbopack-ecmascript/src/parse.rs index cfba4736fa934..bf66e3c80de5c 100644 --- a/crates/turbopack-ecmascript/src/parse.rs +++ b/crates/turbopack-ecmascript/src/parse.rs @@ -30,7 +30,7 @@ use turbopack_core::{ issue::{Issue, IssueExt, IssueSeverity, IssueStage, OptionStyledString, StyledString}, source::Source, source_map::{GenerateSourceMap, OptionSourceMap, SourceMap}, - SOURCE_MAP_ROOT_NAME, + SOURCE_MAP_PREFIX, }; use turbopack_swc_utils::emitter::IssueEmitter; @@ -140,7 +140,7 @@ impl SourceMapGenConfig for InlineSourcesContentConfig { fn file_name_to_source(&self, f: &FileName) -> String { match f { FileName::Custom(s) => { - format!("/{SOURCE_MAP_ROOT_NAME}/{s}") + format!("{SOURCE_MAP_PREFIX}{s}") } _ => f.to_string(), } diff --git a/crates/turbopack-ecmascript/src/references/amd.rs b/crates/turbopack-ecmascript/src/references/amd.rs index 1a804c905aeed..255f60c7ae1eb 100644 --- a/crates/turbopack-ecmascript/src/references/amd.rs +++ b/crates/turbopack-ecmascript/src/references/amd.rs @@ -14,7 +14,7 @@ use turbo_tasks::{ debug::ValueDebugFormat, trace::TraceRawVcs, ReadRef, TryJoinIterExt, Value, ValueToString, Vc, }; use turbopack_core::{ - chunk::ChunkableModuleReference, + chunk::{ChunkableModuleReference, ChunkingContext}, issue::IssueSource, reference::ModuleReference, resolve::{origin::ResolveOrigin, parse::Request, ModuleResolveResult}, @@ -23,7 +23,6 @@ use turbopack_resolve::ecmascript::{cjs_resolve, try_to_severity}; use super::pattern_mapping::{PatternMapping, ResolveType::ChunkItem}; use crate::{ - chunk::EcmascriptChunkingContext, code_gen::{CodeGenerateable, CodeGeneration}, create_visitor, references::AstPath, @@ -139,7 +138,7 @@ impl CodeGenerateable for AmdDefineWithDependenciesCodeGen { #[turbo_tasks::function] async fn code_generation( &self, - chunking_context: Vc>, + chunking_context: Vc>, ) -> Result> { let mut visitors = Vec::new(); diff --git a/crates/turbopack-ecmascript/src/references/async_module.rs b/crates/turbopack-ecmascript/src/references/async_module.rs index d25bb19854f83..2946d3b203236 100644 --- a/crates/turbopack-ecmascript/src/references/async_module.rs +++ b/crates/turbopack-ecmascript/src/references/async_module.rs @@ -8,16 +8,16 @@ use swc_core::{ }; use turbo_tasks::{trace::TraceRawVcs, ReadRef, TryFlatJoinIterExt, TryJoinIterExt, Vc}; use turbopack_core::{ - chunk::{AsyncModuleInfo, ChunkableModule, ChunkableModuleReference, ChunkingType}, + chunk::{ + AsyncModuleInfo, ChunkableModule, ChunkableModuleReference, ChunkingContext, ChunkingType, + }, reference::{ModuleReference, ModuleReferences}, resolve::ExternalType, }; use super::esm::base::ReferencedAsset; use crate::{ - chunk::{EcmascriptChunkPlaceable, EcmascriptChunkingContext}, - code_gen::CodeGeneration, - create_visitor, + chunk::EcmascriptChunkPlaceable, code_gen::CodeGeneration, create_visitor, references::esm::base::insert_hoisted_stmt, }; @@ -102,7 +102,7 @@ impl AsyncModule { #[turbo_tasks::function] async fn get_async_idents( &self, - chunking_context: Vc>, + chunking_context: Vc>, async_module_info: Vc, references: Vc, ) -> Result> { @@ -199,7 +199,7 @@ impl AsyncModule { #[turbo_tasks::function] pub async fn code_generation( self: Vc, - chunking_context: Vc>, + chunking_context: Vc>, async_module_info: Option>, references: Vc, ) -> Result> { diff --git a/crates/turbopack-ecmascript/src/references/cjs.rs b/crates/turbopack-ecmascript/src/references/cjs.rs index e35df7c4f0452..3517016954d68 100644 --- a/crates/turbopack-ecmascript/src/references/cjs.rs +++ b/crates/turbopack-ecmascript/src/references/cjs.rs @@ -6,7 +6,7 @@ use swc_core::{ }; use turbo_tasks::{Value, ValueToString, Vc}; use turbopack_core::{ - chunk::ChunkableModuleReference, + chunk::{ChunkableModuleReference, ChunkingContext}, issue::IssueSource, reference::ModuleReference, resolve::{origin::ResolveOrigin, parse::Request, ModuleResolveResult}, @@ -15,7 +15,6 @@ use turbopack_resolve::ecmascript::{cjs_resolve, try_to_severity}; use super::pattern_mapping::{PatternMapping, ResolveType::ChunkItem}; use crate::{ - chunk::EcmascriptChunkingContext, code_gen::{CodeGenerateable, CodeGeneration}, create_visitor, references::AstPath, @@ -137,7 +136,7 @@ impl CodeGenerateable for CjsRequireAssetReference { #[turbo_tasks::function] async fn code_generation( &self, - chunking_context: Vc>, + chunking_context: Vc>, ) -> Result> { let pm = PatternMapping::resolve_request( self.request, @@ -245,7 +244,7 @@ impl CodeGenerateable for CjsRequireResolveAssetReference { #[turbo_tasks::function] async fn code_generation( &self, - chunking_context: Vc>, + chunking_context: Vc>, ) -> Result> { let pm = PatternMapping::resolve_request( self.request, @@ -306,7 +305,7 @@ impl CodeGenerateable for CjsRequireCacheAccess { #[turbo_tasks::function] async fn code_generation( &self, - _context: Vc>, + _context: Vc>, ) -> Result> { let mut visitors = Vec::new(); diff --git a/crates/turbopack-ecmascript/src/references/constant_condition.rs b/crates/turbopack-ecmascript/src/references/constant_condition.rs index b91b88d0a5a4b..17e51238d5494 100644 --- a/crates/turbopack-ecmascript/src/references/constant_condition.rs +++ b/crates/turbopack-ecmascript/src/references/constant_condition.rs @@ -1,10 +1,10 @@ use anyhow::Result; use swc_core::quote; use turbo_tasks::{Value, Vc}; +use turbopack_core::chunk::ChunkingContext; use super::AstPath; use crate::{ - chunk::EcmascriptChunkingContext, code_gen::{CodeGenerateable, CodeGeneration}, create_visitor, }; @@ -39,7 +39,7 @@ impl CodeGenerateable for ConstantCondition { #[turbo_tasks::function] async fn code_generation( &self, - _context: Vc>, + _context: Vc>, ) -> Result> { let value = self.value; let visitors = [ diff --git a/crates/turbopack-ecmascript/src/references/constant_value.rs b/crates/turbopack-ecmascript/src/references/constant_value.rs index dc93b573b3a4e..c2f94aeed1b62 100644 --- a/crates/turbopack-ecmascript/src/references/constant_value.rs +++ b/crates/turbopack-ecmascript/src/references/constant_value.rs @@ -1,11 +1,10 @@ use anyhow::Result; use swc_core::quote; use turbo_tasks::{Value, Vc}; -use turbopack_core::compile_time_info::CompileTimeDefineValue; +use turbopack_core::{chunk::ChunkingContext, compile_time_info::CompileTimeDefineValue}; use super::AstPath; use crate::{ - chunk::EcmascriptChunkingContext, code_gen::{CodeGenerateable, CodeGeneration}, create_visitor, }; @@ -32,7 +31,7 @@ impl CodeGenerateable for ConstantValue { #[turbo_tasks::function] async fn code_generation( &self, - _context: Vc>, + _context: Vc>, ) -> Result> { let value = self.value.clone(); let path = &self.path.await?; diff --git a/crates/turbopack-ecmascript/src/references/dynamic_expression.rs b/crates/turbopack-ecmascript/src/references/dynamic_expression.rs index 8f5e06e4840c8..6aee2d0e6e387 100644 --- a/crates/turbopack-ecmascript/src/references/dynamic_expression.rs +++ b/crates/turbopack-ecmascript/src/references/dynamic_expression.rs @@ -2,10 +2,10 @@ use anyhow::Result; use serde::{Deserialize, Serialize}; use swc_core::quote; use turbo_tasks::{debug::ValueDebugFormat, trace::TraceRawVcs, Vc}; +use turbopack_core::chunk::ChunkingContext; use super::AstPath; use crate::{ - chunk::EcmascriptChunkingContext, code_gen::{CodeGenerateable, CodeGeneration}, create_visitor, }; @@ -46,7 +46,7 @@ impl CodeGenerateable for DynamicExpression { #[turbo_tasks::function] async fn code_generation( &self, - _context: Vc>, + _context: Vc>, ) -> Result> { let path = &self.path.await?; diff --git a/crates/turbopack-ecmascript/src/references/esm/base.rs b/crates/turbopack-ecmascript/src/references/esm/base.rs index 7c56d73cbf665..2488398c46052 100644 --- a/crates/turbopack-ecmascript/src/references/esm/base.rs +++ b/crates/turbopack-ecmascript/src/references/esm/base.rs @@ -14,7 +14,7 @@ use turbopack_core::{ issue::{IssueSeverity, IssueSource}, module::Module, reference::ModuleReference, - reference_type::EcmaScriptModulesReferenceSubType, + reference_type::{EcmaScriptModulesReferenceSubType, ImportWithType}, resolve::{ origin::{ResolveOrigin, ResolveOriginExt}, parse::Request, @@ -25,7 +25,7 @@ use turbopack_resolve::ecmascript::esm_resolve; use crate::{ analyzer::imports::ImportAnnotations, - chunk::{EcmascriptChunkPlaceable, EcmascriptChunkingContext}, + chunk::EcmascriptChunkPlaceable, code_gen::{CodeGenerateable, CodeGeneration}, create_visitor, magic_identifier, references::util::{request_to_string, throw_module_not_found_expr}, @@ -142,15 +142,18 @@ impl EsmAssetReference { impl ModuleReference for EsmAssetReference { #[turbo_tasks::function] async fn resolve_reference(&self) -> Result> { - let ty = Value::new(match &self.export_name { - Some(part) => EcmaScriptModulesReferenceSubType::ImportPart(*part), - None => EcmaScriptModulesReferenceSubType::Import, - }); + let ty = if matches!(self.annotations.module_type(), Some("json")) { + EcmaScriptModulesReferenceSubType::ImportWithType(ImportWithType::Json) + } else if let Some(part) = &self.export_name { + EcmaScriptModulesReferenceSubType::ImportPart(*part) + } else { + EcmaScriptModulesReferenceSubType::Import + }; Ok(esm_resolve( self.get_origin().resolve().await?, self.request, - ty, + Value::new(ty), IssueSeverity::Error.cell(), self.issue_source, )) @@ -162,7 +165,7 @@ impl ValueToString for EsmAssetReference { #[turbo_tasks::function] async fn to_string(&self) -> Result> { Ok(Vc::cell(format!( - "import {} {}", + "import {} with {}", self.request.to_string().await?, self.annotations ))) @@ -192,7 +195,7 @@ impl CodeGenerateable for EsmAssetReference { #[turbo_tasks::function] async fn code_generation( self: Vc, - chunking_context: Vc>, + chunking_context: Vc>, ) -> Result> { let mut visitors = Vec::new(); diff --git a/crates/turbopack-ecmascript/src/references/esm/binding.rs b/crates/turbopack-ecmascript/src/references/esm/binding.rs index 44d198edc8b35..3942774ae76d4 100644 --- a/crates/turbopack-ecmascript/src/references/esm/binding.rs +++ b/crates/turbopack-ecmascript/src/references/esm/binding.rs @@ -10,10 +10,10 @@ use swc_core::{ }, }; use turbo_tasks::Vc; +use turbopack_core::chunk::ChunkingContext; use super::EsmAssetReference; use crate::{ - chunk::EcmascriptChunkingContext, code_gen::{CodeGenerateable, CodeGeneration}, create_visitor, references::AstPath, @@ -49,7 +49,7 @@ impl CodeGenerateable for EsmBinding { #[turbo_tasks::function] async fn code_generation( self: Vc, - _context: Vc>, + _context: Vc>, ) -> Result> { let this = self.await?; let mut visitors = Vec::new(); diff --git a/crates/turbopack-ecmascript/src/references/esm/dynamic.rs b/crates/turbopack-ecmascript/src/references/esm/dynamic.rs index cb8f05a564b71..2695d974d93c4 100644 --- a/crates/turbopack-ecmascript/src/references/esm/dynamic.rs +++ b/crates/turbopack-ecmascript/src/references/esm/dynamic.rs @@ -17,7 +17,6 @@ use turbopack_resolve::ecmascript::{esm_resolve, try_to_severity}; use super::super::pattern_mapping::{PatternMapping, ResolveType}; use crate::{ - chunk::EcmascriptChunkingContext, code_gen::{CodeGenerateable, CodeGeneration}, create_visitor, references::AstPath, @@ -94,7 +93,7 @@ impl CodeGenerateable for EsmAsyncAssetReference { #[turbo_tasks::function] async fn code_generation( &self, - chunking_context: Vc>, + chunking_context: Vc>, ) -> Result> { let pm = PatternMapping::resolve_request( self.request, diff --git a/crates/turbopack-ecmascript/src/references/esm/export.rs b/crates/turbopack-ecmascript/src/references/esm/export.rs index facabf294fcba..41807de8d19ed 100644 --- a/crates/turbopack-ecmascript/src/references/esm/export.rs +++ b/crates/turbopack-ecmascript/src/references/esm/export.rs @@ -17,6 +17,7 @@ use swc_core::{ use turbo_tasks::{trace::TraceRawVcs, TryFlatJoinIterExt, ValueToString, Vc}; use turbo_tasks_fs::glob::Glob; use turbopack_core::{ + chunk::ChunkingContext, ident::AssetIdent, issue::{analyze::AnalyzeIssue, IssueExt, IssueSeverity, StyledString}, module::Module, @@ -25,7 +26,7 @@ use turbopack_core::{ use super::base::ReferencedAsset; use crate::{ - chunk::{EcmascriptChunkPlaceable, EcmascriptChunkingContext, EcmascriptExports}, + chunk::{EcmascriptChunkPlaceable, EcmascriptExports}, code_gen::{CodeGenerateable, CodeGeneration}, create_visitor, references::esm::base::insert_hoisted_stmt, @@ -409,7 +410,7 @@ impl CodeGenerateable for EsmExports { #[turbo_tasks::function] async fn code_generation( self: Vc, - _context: Vc>, + _context: Vc>, ) -> Result> { let mut visitors = Vec::new(); diff --git a/crates/turbopack-ecmascript/src/references/esm/meta.rs b/crates/turbopack-ecmascript/src/references/esm/meta.rs index 7a8790f21186f..3ec0e1728d484 100644 --- a/crates/turbopack-ecmascript/src/references/esm/meta.rs +++ b/crates/turbopack-ecmascript/src/references/esm/meta.rs @@ -8,9 +8,9 @@ use swc_core::{ }; use turbo_tasks::Vc; use turbo_tasks_fs::FileSystemPath; +use turbopack_core::chunk::ChunkingContext; use crate::{ - chunk::EcmascriptChunkingContext, code_gen::{CodeGenerateable, CodeGeneration}, create_visitor, magic_identifier, references::{as_abs_path, esm::base::insert_hoisted_stmt, AstPath}, @@ -40,7 +40,7 @@ impl CodeGenerateable for ImportMetaBinding { #[turbo_tasks::function] async fn code_generation( &self, - _context: Vc>, + _context: Vc>, ) -> Result> { let path = as_abs_path(self.path).await?.as_str().map_or_else( || { @@ -100,7 +100,7 @@ impl CodeGenerateable for ImportMetaRef { #[turbo_tasks::function] async fn code_generation( &self, - _context: Vc>, + _context: Vc>, ) -> Result> { let ast_path = &self.ast_path.await?; let visitor = create_visitor!(ast_path, visit_mut_expr(expr: &mut Expr) { diff --git a/crates/turbopack-ecmascript/src/references/esm/module_id.rs b/crates/turbopack-ecmascript/src/references/esm/module_id.rs index ab74a9ba90cc9..835a009212bcf 100644 --- a/crates/turbopack-ecmascript/src/references/esm/module_id.rs +++ b/crates/turbopack-ecmascript/src/references/esm/module_id.rs @@ -3,7 +3,8 @@ use swc_core::{ecma::ast::Expr, quote}; use turbo_tasks::{ValueToString, Vc}; use turbopack_core::{ chunk::{ - ChunkItemExt, ChunkableModule, ChunkableModuleReference, ChunkingTypeOption, ModuleId, + ChunkItemExt, ChunkableModule, ChunkableModuleReference, ChunkingContext, + ChunkingTypeOption, ModuleId, }, reference::ModuleReference, resolve::ModuleResolveResult, @@ -11,7 +12,6 @@ use turbopack_core::{ use super::{base::ReferencedAsset, EsmAssetReference}; use crate::{ - chunk::EcmascriptChunkingContext, code_gen::{CodeGenerateable, CodeGeneration}, create_visitor, references::AstPath, @@ -64,7 +64,7 @@ impl CodeGenerateable for EsmModuleIdAssetReference { #[turbo_tasks::function] async fn code_generation( &self, - chunking_context: Vc>, + chunking_context: Vc>, ) -> Result> { let mut visitors = Vec::new(); diff --git a/crates/turbopack-ecmascript/src/references/esm/module_item.rs b/crates/turbopack-ecmascript/src/references/esm/module_item.rs index 269910a7b015c..a41ba2b5d6b2a 100644 --- a/crates/turbopack-ecmascript/src/references/esm/module_item.rs +++ b/crates/turbopack-ecmascript/src/references/esm/module_item.rs @@ -10,9 +10,9 @@ use swc_core::{ quote, }; use turbo_tasks::Vc; +use turbopack_core::chunk::ChunkingContext; use crate::{ - chunk::EcmascriptChunkingContext, code_gen::{CodeGenerateable, CodeGeneration}, create_visitor, magic_identifier, references::AstPath, @@ -40,7 +40,7 @@ impl CodeGenerateable for EsmModuleItem { #[turbo_tasks::function] async fn code_generation( &self, - _context: Vc>, + _context: Vc>, ) -> Result> { let mut visitors = Vec::new(); diff --git a/crates/turbopack-ecmascript/src/references/esm/url.rs b/crates/turbopack-ecmascript/src/references/esm/url.rs index 97a640e982a9c..5716fe5ec04c2 100644 --- a/crates/turbopack-ecmascript/src/references/esm/url.rs +++ b/crates/turbopack-ecmascript/src/references/esm/url.rs @@ -6,7 +6,8 @@ use swc_core::{ use turbo_tasks::{Value, ValueToString, Vc}; use turbopack_core::{ chunk::{ - ChunkItemExt, ChunkableModule, ChunkableModuleReference, ChunkingType, ChunkingTypeOption, + ChunkItemExt, ChunkableModule, ChunkableModuleReference, ChunkingContext, ChunkingType, + ChunkingTypeOption, }, environment::Rendering, issue::IssueSource, @@ -20,7 +21,6 @@ use turbopack_resolve::ecmascript::try_to_severity; use super::base::ReferencedAsset; use crate::{ - chunk::EcmascriptChunkingContext, code_gen::{CodeGenerateable, CodeGeneration}, create_visitor, references::AstPath, @@ -142,7 +142,7 @@ impl CodeGenerateable for UrlAssetReference { #[turbo_tasks::function] async fn code_generation( self: Vc, - chunking_context: Vc>, + chunking_context: Vc>, ) -> Result> { let this = self.await?; let mut visitors = vec![]; diff --git a/crates/turbopack-ecmascript/src/references/mod.rs b/crates/turbopack-ecmascript/src/references/mod.rs index 37ec2c7953cb7..e651e0f7f00c9 100644 --- a/crates/turbopack-ecmascript/src/references/mod.rs +++ b/crates/turbopack-ecmascript/src/references/mod.rs @@ -29,10 +29,12 @@ use constant_value::ConstantValue; use indexmap::IndexSet; use lazy_static::lazy_static; use num_traits::Zero; +use once_cell::sync::Lazy; use parking_lot::Mutex; use regex::Regex; use sourcemap::decode_data_url; use swc_core::{ + atoms::JsWord, common::{ comments::{CommentKind, Comments}, errors::{DiagnosticId, Handler, HANDLER}, @@ -113,7 +115,7 @@ use crate::{ analyzer::{ builtin::early_replace_builtin, graph::{ConditionalKind, EffectArg, EvalContext, VarGraph}, - imports::{ImportedSymbol, Reexport}, + imports::{ImportAnnotations, ImportedSymbol, Reexport}, parse_require_context, top_level_await::has_top_level_await, ConstantNumber, ConstantString, ModuleValue, RequireContextValue, @@ -388,6 +390,7 @@ pub(crate) async fn analyse_ecmascript_module_internal( let transforms = raw_module.transforms; let options = raw_module.options; let compile_time_info = raw_module.compile_time_info; + let options = options.await?; let import_externals = options.import_externals; let origin = Vc::upcast::>(module); @@ -2791,18 +2794,12 @@ async fn resolve_as_webpack_runtime( #[turbo_tasks::value(transparent, serialization = "none")] pub struct AstPath(#[turbo_tasks(trace_ignore)] Vec); -pub static TURBOPACK_HELPER: &str = "__turbopackHelper"; +pub static TURBOPACK_HELPER: Lazy = Lazy::new(|| "__turbopack-helper__".into()); pub fn is_turbopack_helper_import(import: &ImportDecl) -> bool { - import.with.as_ref().map_or(false, |asserts| { - asserts.props.iter().any(|assert| { - assert - .as_prop() - .and_then(|prop| prop.as_key_value()) - .and_then(|kv| kv.key.as_ident()) - .map_or(false, |ident| &*ident.sym == TURBOPACK_HELPER) - }) - }) + let annotations = ImportAnnotations::parse(import.with.as_deref()); + + annotations.get(&TURBOPACK_HELPER).is_some() } #[derive(Debug)] diff --git a/crates/turbopack-ecmascript/src/references/require_context.rs b/crates/turbopack-ecmascript/src/references/require_context.rs index df465c763af00..1ae94b46a65b6 100644 --- a/crates/turbopack-ecmascript/src/references/require_context.rs +++ b/crates/turbopack-ecmascript/src/references/require_context.rs @@ -1,6 +1,6 @@ use std::{borrow::Cow, collections::VecDeque, sync::Arc}; -use anyhow::{bail, Context, Result}; +use anyhow::{bail, Result}; use indexmap::IndexMap; use swc_core::{ common::DUMMY_SP, @@ -32,8 +32,7 @@ use turbopack_resolve::ecmascript::{cjs_resolve, try_to_severity}; use crate::{ chunk::{ - EcmascriptChunkItem, EcmascriptChunkItemContent, EcmascriptChunkType, - EcmascriptChunkingContext, EcmascriptExports, + EcmascriptChunkItem, EcmascriptChunkItemContent, EcmascriptChunkType, EcmascriptExports, }, code_gen::CodeGeneration, create_visitor, @@ -280,7 +279,7 @@ impl CodeGenerateable for RequireContextAssetReference { #[turbo_tasks::function] async fn code_generation( &self, - chunking_context: Vc>, + chunking_context: Vc>, ) -> Result> { let chunk_item = self.inner.as_chunk_item(Vc::upcast(chunking_context)); let module_id = chunk_item.id().await?.clone_value(); @@ -379,13 +378,6 @@ impl ChunkableModule for RequireContextAsset { self: Vc, chunking_context: Vc>, ) -> Result>> { - let chunking_context = - Vc::try_resolve_downcast::>(chunking_context) - .await? - .context( - "chunking context must impl EcmascriptChunkingContext to use \ - RequireContextAsset", - )?; let this = self.await?; Ok(Vc::upcast( RequireContextChunkItem { @@ -410,7 +402,7 @@ impl EcmascriptChunkPlaceable for RequireContextAsset { #[turbo_tasks::value] pub struct RequireContextChunkItem { - chunking_context: Vc>, + chunking_context: Vc>, inner: Vc, origin: Vc>, @@ -420,7 +412,7 @@ pub struct RequireContextChunkItem { #[turbo_tasks::value_impl] impl EcmascriptChunkItem for RequireContextChunkItem { #[turbo_tasks::function] - fn chunking_context(&self) -> Vc> { + fn chunking_context(&self) -> Vc> { self.chunking_context } diff --git a/crates/turbopack-ecmascript/src/references/unreachable.rs b/crates/turbopack-ecmascript/src/references/unreachable.rs index e7db8159f1ad4..77365b0a3c527 100644 --- a/crates/turbopack-ecmascript/src/references/unreachable.rs +++ b/crates/turbopack-ecmascript/src/references/unreachable.rs @@ -1,10 +1,10 @@ use anyhow::Result; use swc_core::quote; use turbo_tasks::Vc; +use turbopack_core::chunk::ChunkingContext; use super::AstPath; use crate::{ - chunk::EcmascriptChunkingContext, code_gen::{CodeGenerateable, CodeGeneration}, create_visitor, }; @@ -27,7 +27,7 @@ impl CodeGenerateable for Unreachable { #[turbo_tasks::function] async fn code_generation( &self, - _context: Vc>, + _context: Vc>, ) -> Result> { let path = self.path.await?; let visitors = [ diff --git a/crates/turbopack-ecmascript/src/side_effect_optimization/facade/chunk_item.rs b/crates/turbopack-ecmascript/src/side_effect_optimization/facade/chunk_item.rs index 0af193e7faec3..b6360a1b6b780 100644 --- a/crates/turbopack-ecmascript/src/side_effect_optimization/facade/chunk_item.rs +++ b/crates/turbopack-ecmascript/src/side_effect_optimization/facade/chunk_item.rs @@ -22,8 +22,7 @@ use super::module::EcmascriptModuleFacadeModule; use crate::{ chunk::{ EcmascriptChunkItem, EcmascriptChunkItemContent, EcmascriptChunkItemOptions, - EcmascriptChunkPlaceable, EcmascriptChunkType, EcmascriptChunkingContext, - EcmascriptExports, + EcmascriptChunkPlaceable, EcmascriptChunkType, EcmascriptExports, }, code_gen::{CodeGenerateable, CodeGenerateableWithAsyncModuleInfo}, path_visitor::ApplyVisitors, @@ -33,7 +32,7 @@ use crate::{ #[turbo_tasks::value(shared)] pub struct EcmascriptModuleFacadeChunkItem { pub(crate) module: Vc, - pub(crate) chunking_context: Vc>, + pub(crate) chunking_context: Vc>, } #[turbo_tasks::value_impl] @@ -150,7 +149,7 @@ impl EcmascriptChunkItem for EcmascriptModuleFacadeChunkItem { } #[turbo_tasks::function] - fn chunking_context(&self) -> Vc> { + fn chunking_context(&self) -> Vc> { self.chunking_context } } diff --git a/crates/turbopack-ecmascript/src/side_effect_optimization/facade/module.rs b/crates/turbopack-ecmascript/src/side_effect_optimization/facade/module.rs index 511e9bf211cbd..517f3093a0086 100644 --- a/crates/turbopack-ecmascript/src/side_effect_optimization/facade/module.rs +++ b/crates/turbopack-ecmascript/src/side_effect_optimization/facade/module.rs @@ -1,6 +1,6 @@ use std::collections::BTreeMap; -use anyhow::{bail, Context, Result}; +use anyhow::{bail, Result}; use turbo_tasks::Vc; use turbo_tasks_fs::{glob::Glob, File, FileContent}; use turbopack_core::{ @@ -14,7 +14,7 @@ use turbopack_core::{ use super::chunk_item::EcmascriptModuleFacadeChunkItem; use crate::{ - chunk::{EcmascriptChunkPlaceable, EcmascriptChunkingContext, EcmascriptExports}, + chunk::{EcmascriptChunkPlaceable, EcmascriptExports}, references::{ async_module::{AsyncModule, OptionAsyncModule}, esm::{EsmExport, EsmExports}, @@ -278,13 +278,6 @@ impl ChunkableModule for EcmascriptModuleFacadeModule { self: Vc, chunking_context: Vc>, ) -> Result>> { - let chunking_context = - Vc::try_resolve_downcast::>(chunking_context) - .await? - .context( - "chunking context must impl EcmascriptChunkingContext to use \ - EcmascriptModuleFacadeModule", - )?; Ok(Vc::upcast( EcmascriptModuleFacadeChunkItem { module: self, diff --git a/crates/turbopack-ecmascript/src/side_effect_optimization/locals/chunk_item.rs b/crates/turbopack-ecmascript/src/side_effect_optimization/locals/chunk_item.rs index eff4af09a5dc1..84199f6c806ec 100644 --- a/crates/turbopack-ecmascript/src/side_effect_optimization/locals/chunk_item.rs +++ b/crates/turbopack-ecmascript/src/side_effect_optimization/locals/chunk_item.rs @@ -11,7 +11,7 @@ use super::module::EcmascriptModuleLocalsModule; use crate::{ chunk::{ EcmascriptChunkItem, EcmascriptChunkItemContent, EcmascriptChunkPlaceable, - EcmascriptChunkType, EcmascriptChunkingContext, + EcmascriptChunkType, }, EcmascriptModuleContent, }; @@ -20,7 +20,7 @@ use crate::{ #[turbo_tasks::value(shared)] pub struct EcmascriptModuleLocalsChunkItem { pub(super) module: Vc, - pub(super) chunking_context: Vc>, + pub(super) chunking_context: Vc>, } #[turbo_tasks::value_impl] @@ -63,12 +63,13 @@ impl EcmascriptChunkItem for EcmascriptModuleLocalsChunkItem { Ok(EcmascriptChunkItemContent::new( content, self.chunking_context, + original_module.await?.options, async_module_options, )) } #[turbo_tasks::function] - fn chunking_context(&self) -> Vc> { + fn chunking_context(&self) -> Vc> { self.chunking_context } } diff --git a/crates/turbopack-ecmascript/src/side_effect_optimization/locals/module.rs b/crates/turbopack-ecmascript/src/side_effect_optimization/locals/module.rs index 98b4ff8760aa6..a733b44cb1a7e 100644 --- a/crates/turbopack-ecmascript/src/side_effect_optimization/locals/module.rs +++ b/crates/turbopack-ecmascript/src/side_effect_optimization/locals/module.rs @@ -1,6 +1,6 @@ use std::collections::BTreeMap; -use anyhow::{bail, Context, Result}; +use anyhow::{bail, Result}; use turbo_tasks::Vc; use turbo_tasks_fs::glob::Glob; use turbopack_core::{ @@ -14,7 +14,7 @@ use turbopack_core::{ use super::chunk_item::EcmascriptModuleLocalsChunkItem; use crate::{ - chunk::{EcmascriptChunkPlaceable, EcmascriptChunkingContext, EcmascriptExports}, + chunk::{EcmascriptChunkPlaceable, EcmascriptExports}, references::{ async_module::OptionAsyncModule, esm::{EsmExport, EsmExports}, @@ -113,13 +113,6 @@ impl ChunkableModule for EcmascriptModuleLocalsModule { self: Vc, chunking_context: Vc>, ) -> Result>> { - let chunking_context = - Vc::try_resolve_downcast::>(chunking_context) - .await? - .context( - "chunking context must impl EcmascriptChunkingContext to use \ - EcmascriptModuleLocalsModule", - )?; Ok(Vc::upcast( EcmascriptModuleLocalsChunkItem { module: self, diff --git a/crates/turbopack-ecmascript/src/side_effect_optimization/reference.rs b/crates/turbopack-ecmascript/src/side_effect_optimization/reference.rs index 833d033876435..8eba01e9fcc43 100644 --- a/crates/turbopack-ecmascript/src/side_effect_optimization/reference.rs +++ b/crates/turbopack-ecmascript/src/side_effect_optimization/reference.rs @@ -7,8 +7,8 @@ use swc_core::{ use turbo_tasks::{ValueToString, Vc}; use turbopack_core::{ chunk::{ - ChunkItemExt, ChunkableModule, ChunkableModuleReference, ChunkingType, ChunkingTypeOption, - ModuleId, + ChunkItemExt, ChunkableModule, ChunkableModuleReference, ChunkingContext, ChunkingType, + ChunkingTypeOption, ModuleId, }, reference::ModuleReference, resolve::{ModulePart, ModuleResolveResult}, @@ -18,7 +18,7 @@ use super::{ facade::module::EcmascriptModuleFacadeModule, locals::module::EcmascriptModuleLocalsModule, }; use crate::{ - chunk::{EcmascriptChunkPlaceable, EcmascriptChunkingContext}, + chunk::EcmascriptChunkPlaceable, code_gen::{CodeGenerateable, CodeGeneration}, create_visitor, references::esm::base::{insert_hoisted_stmt, ReferencedAsset}, @@ -110,7 +110,7 @@ impl CodeGenerateable for EcmascriptModulePartReference { #[turbo_tasks::function] async fn code_generation( self: Vc, - chunking_context: Vc>, + chunking_context: Vc>, ) -> Result> { let mut visitors = Vec::new(); diff --git a/crates/turbopack-ecmascript/src/tree_shake/asset.rs b/crates/turbopack-ecmascript/src/tree_shake/asset.rs index 294e416a6dccf..2ee105a67be7e 100644 --- a/crates/turbopack-ecmascript/src/tree_shake/asset.rs +++ b/crates/turbopack-ecmascript/src/tree_shake/asset.rs @@ -11,7 +11,7 @@ use turbopack_core::{ use super::{chunk_item::EcmascriptModulePartChunkItem, get_part_id, split_module, SplitResult}; use crate::{ - chunk::{EcmascriptChunkPlaceable, EcmascriptChunkingContext, EcmascriptExports}, + chunk::{EcmascriptChunkPlaceable, EcmascriptExports}, references::analyse_ecmascript_module, AnalyzeEcmascriptModuleResult, EcmascriptModuleAsset, }; @@ -122,13 +122,6 @@ impl ChunkableModule for EcmascriptModulePartAsset { self: Vc, chunking_context: Vc>, ) -> Result>> { - let chunking_context = - Vc::try_resolve_downcast::>(chunking_context) - .await? - .context( - "chunking context must impl EcmascriptChunkingContext to use \ - EcmascriptModulePartAsset", - )?; Ok(Vc::upcast( EcmascriptModulePartChunkItem { module: self, diff --git a/crates/turbopack-ecmascript/src/tree_shake/chunk_item.rs b/crates/turbopack-ecmascript/src/tree_shake/chunk_item.rs index a9d3d69e1cb2d..9bd514b1d2f1f 100644 --- a/crates/turbopack-ecmascript/src/tree_shake/chunk_item.rs +++ b/crates/turbopack-ecmascript/src/tree_shake/chunk_item.rs @@ -9,10 +9,7 @@ use turbopack_core::{ use super::{asset::EcmascriptModulePartAsset, part_of_module, split_module}; use crate::{ - chunk::{ - EcmascriptChunkItem, EcmascriptChunkItemContent, EcmascriptChunkType, - EcmascriptChunkingContext, - }, + chunk::{EcmascriptChunkItem, EcmascriptChunkItemContent, EcmascriptChunkType}, EcmascriptModuleContent, }; @@ -23,7 +20,7 @@ use crate::{ #[turbo_tasks::value(shared)] pub struct EcmascriptModulePartChunkItem { pub(super) module: Vc, - pub(super) chunking_context: Vc>, + pub(super) chunking_context: Vc>, } #[turbo_tasks::value_impl] @@ -65,12 +62,13 @@ impl EcmascriptChunkItem for EcmascriptModulePartChunkItem { Ok(EcmascriptChunkItemContent::new( content, this.chunking_context, + module.full_module.await?.options, async_module_options, )) } #[turbo_tasks::function] - fn chunking_context(&self) -> Vc> { + fn chunking_context(&self) -> Vc> { self.chunking_context } } diff --git a/crates/turbopack-json/src/lib.rs b/crates/turbopack-json/src/lib.rs index 1a5d6885c9ba0..244f2a2f91529 100644 --- a/crates/turbopack-json/src/lib.rs +++ b/crates/turbopack-json/src/lib.rs @@ -10,7 +10,7 @@ use std::fmt::Write; -use anyhow::{bail, Context, Error, Result}; +use anyhow::{bail, Error, Result}; use turbo_tasks::{ValueToString, Vc}; use turbo_tasks_fs::{FileContent, FileJsonContent}; use turbopack_core::{ @@ -23,7 +23,7 @@ use turbopack_core::{ }; use turbopack_ecmascript::chunk::{ EcmascriptChunkItem, EcmascriptChunkItemContent, EcmascriptChunkPlaceable, EcmascriptChunkType, - EcmascriptChunkingContext, EcmascriptExports, + EcmascriptExports, }; #[turbo_tasks::function] @@ -67,12 +67,6 @@ impl ChunkableModule for JsonModuleAsset { self: Vc, chunking_context: Vc>, ) -> Result>> { - let chunking_context = - Vc::try_resolve_downcast::>(chunking_context) - .await? - .context( - "chunking context must impl EcmascriptChunkingContext to use JsonModuleAsset", - )?; Ok(Vc::upcast(JsonChunkItem::cell(JsonChunkItem { module: self, chunking_context, @@ -91,7 +85,7 @@ impl EcmascriptChunkPlaceable for JsonModuleAsset { #[turbo_tasks::value] struct JsonChunkItem { module: Vc, - chunking_context: Vc>, + chunking_context: Vc>, } #[turbo_tasks::value_impl] @@ -127,7 +121,7 @@ impl ChunkItem for JsonChunkItem { #[turbo_tasks::value_impl] impl EcmascriptChunkItem for JsonChunkItem { #[turbo_tasks::function] - fn chunking_context(&self) -> Vc> { + fn chunking_context(&self) -> Vc> { self.chunking_context } diff --git a/crates/turbopack-mdx/src/lib.rs b/crates/turbopack-mdx/src/lib.rs index ad3f0447aef08..bb6163e67fd5b 100644 --- a/crates/turbopack-mdx/src/lib.rs +++ b/crates/turbopack-mdx/src/lib.rs @@ -19,11 +19,11 @@ use turbopack_core::{ use turbopack_ecmascript::{ chunk::{ EcmascriptChunkItem, EcmascriptChunkItemContent, EcmascriptChunkPlaceable, - EcmascriptChunkType, EcmascriptChunkingContext, EcmascriptExports, + EcmascriptChunkType, EcmascriptExports, }, references::AnalyzeEcmascriptModuleResultBuilder, AnalyzeEcmascriptModuleResult, EcmascriptInputTransforms, EcmascriptModuleAsset, - EcmascriptModuleAssetType, + EcmascriptModuleAssetType, EcmascriptOptions, }; #[turbo_tasks::function] @@ -162,7 +162,7 @@ async fn into_ecmascript_module_asset( analyze_types: false, }), this.transforms, - Value::new(Default::default()), + EcmascriptOptions::default().cell(), this.asset_context.compile_time_info(), )) } @@ -230,12 +230,6 @@ impl ChunkableModule for MdxModuleAsset { self: Vc, chunking_context: Vc>, ) -> Result>> { - let chunking_context = - Vc::try_resolve_downcast::>(chunking_context) - .await? - .context( - "chunking context must impl EcmascriptChunkingContext to use MdxModuleAsset", - )?; Ok(Vc::upcast(MdxChunkItem::cell(MdxChunkItem { module: self, chunking_context, @@ -267,7 +261,7 @@ impl ResolveOrigin for MdxModuleAsset { #[turbo_tasks::value] struct MdxChunkItem { module: Vc, - chunking_context: Vc>, + chunking_context: Vc>, } #[turbo_tasks::value_impl] @@ -303,7 +297,7 @@ impl ChunkItem for MdxChunkItem { #[turbo_tasks::value_impl] impl EcmascriptChunkItem for MdxChunkItem { #[turbo_tasks::function] - fn chunking_context(&self) -> Vc> { + fn chunking_context(&self) -> Vc> { self.chunking_context } diff --git a/crates/turbopack-node/js/src/transforms/webpack-loaders.ts b/crates/turbopack-node/js/src/transforms/webpack-loaders.ts index 71f5f775361fb..ff254a0bccd04 100644 --- a/crates/turbopack-node/js/src/transforms/webpack-loaders.ts +++ b/crates/turbopack-node/js/src/transforms/webpack-loaders.ts @@ -132,6 +132,10 @@ class DummySpan { async traceAsyncFn(fn: (span: DummySpan) => T | Promise): Promise { return await fn(this); } + + stop() { + return; + } } type ResolveOptions = { diff --git a/crates/turbopack-node/src/route_matcher.rs b/crates/turbopack-node/src/route_matcher.rs index 18ef21acd1358..4341da5d97a17 100644 --- a/crates/turbopack-node/src/route_matcher.rs +++ b/crates/turbopack-node/src/route_matcher.rs @@ -1,7 +1,7 @@ use indexmap::IndexMap; use turbo_tasks::Vc; -#[turbo_tasks::value(transparent)] +#[turbo_tasks::value] #[derive(Debug, Clone)] #[serde(untagged)] pub enum Param { diff --git a/crates/turbopack-node/src/source_map/mod.rs b/crates/turbopack-node/src/source_map/mod.rs index 796057b20957f..28484719207c1 100644 --- a/crates/turbopack-node/src/source_map/mod.rs +++ b/crates/turbopack-node/src/source_map/mod.rs @@ -16,8 +16,7 @@ use turbo_tasks_fs::{ }; use turbopack_cli_utils::source_context::format_source_context_lines; use turbopack_core::{ - output::OutputAsset, source_map::GenerateSourceMap, PROJECT_FILESYSTEM_NAME, - SOURCE_MAP_ROOT_NAME, + output::OutputAsset, source_map::GenerateSourceMap, PROJECT_FILESYSTEM_NAME, SOURCE_MAP_PREFIX, }; use turbopack_ecmascript::magic_identifier::unmangle_identifiers; @@ -233,9 +232,8 @@ async fn resolve_source_mapping( TraceResult::Found(frame) => { let lib_code = frame.file.contains("/node_modules/"); if let Some(project_path) = frame.file.strip_prefix(concatcp!( - "/", - SOURCE_MAP_ROOT_NAME, - "/[", + SOURCE_MAP_PREFIX, + "[", PROJECT_FILESYSTEM_NAME, "]/" )) { diff --git a/crates/turbopack-node/src/transforms/postcss.rs b/crates/turbopack-node/src/transforms/postcss.rs index 05e423ebf156b..8b242611ad2e6 100644 --- a/crates/turbopack-node/src/transforms/postcss.rs +++ b/crates/turbopack-node/src/transforms/postcss.rs @@ -36,7 +36,7 @@ use crate::{ #[derive(Debug, Serialize, Deserialize, Clone)] #[serde(rename_all = "camelCase")] -#[turbo_tasks::value(transparent, serialization = "custom")] +#[turbo_tasks::value(serialization = "custom")] struct PostCssProcessingResult { css: String, map: Option, @@ -248,9 +248,10 @@ pub(crate) async fn config_loader_source( // Bundling would break the ability to use `require.resolve` in the config file. let code = formatdoc! { r#" - import {{ pathToFileURL }} from 'url'; + import {{ pathToFileURL }} from 'node:url'; + import path from 'node:path'; - const configPath = `${{process.cwd()}}/${{{config_path}}}`; + const configPath = path.join(process.cwd(), {config_path}); // Absolute paths don't work with ESM imports on Windows: // https://github.com/nodejs/node/issues/31710 // convert it to a file:// URL, which works on all platforms diff --git a/crates/turbopack-node/src/transforms/webpack.rs b/crates/turbopack-node/src/transforms/webpack.rs index c5de1d32a26ba..745ca87cb0cfd 100644 --- a/crates/turbopack-node/src/transforms/webpack.rs +++ b/crates/turbopack-node/src/transforms/webpack.rs @@ -54,7 +54,7 @@ use crate::{ #[derive(Debug, Serialize, Deserialize, Clone)] #[serde(rename_all = "camelCase")] -#[turbo_tasks::value(transparent, serialization = "custom")] +#[turbo_tasks::value(serialization = "custom")] struct WebpackLoadersProcessingResult { source: String, map: Option, @@ -204,7 +204,11 @@ impl WebpackLoadersProcessedAsset { .await? .get_relative_path_to(&resource_fs_path_ref) else { - bail!("Resource path need to be on project filesystem"); + bail!(format!( + "Resource path \"{}\" need to be on project filesystem \"{}\"", + resource_fs_path_ref, + project_path.await? + )); }; let loaders = transform.loaders.await?; let config_value = evaluate_webpack_loader(WebpackLoaderContext { diff --git a/crates/turbopack-nodejs/src/chunking_context.rs b/crates/turbopack-nodejs/src/chunking_context.rs index 2cc5e29769674..438c8dc7eb624 100644 --- a/crates/turbopack-nodejs/src/chunking_context.rs +++ b/crates/turbopack-nodejs/src/chunking_context.rs @@ -18,7 +18,7 @@ use turbopack_core::{ }; use turbopack_ecmascript::{ async_chunk::module::AsyncLoaderModule, - chunk::{EcmascriptChunk, EcmascriptChunkPlaceable, EcmascriptChunkingContext}, + chunk::{EcmascriptChunk, EcmascriptChunkPlaceable}, manifest::{chunk_asset::ManifestAsyncModule, loader_item::ManifestLoaderChunkItem}, }; use turbopack_ecmascript_runtime::RuntimeType; @@ -274,24 +274,6 @@ impl ChunkingContext for NodeJsChunkingContext { Vc::cell(true) } - #[turbo_tasks::function] - async fn can_be_in_same_chunk( - &self, - asset_a: Vc>, - asset_b: Vc>, - ) -> Result> { - let parent_dir = asset_a.ident().path().parent().await?; - - let path = asset_b.ident().path().await?; - if let Some(rel_path) = parent_dir.get_path_to(&path) { - if !rel_path.starts_with("node_modules/") && !rel_path.contains("/node_modules/") { - return Ok(Vc::cell(true)); - } - } - - Ok(Vc::cell(false)) - } - #[turbo_tasks::function] async fn asset_path( &self, @@ -395,6 +377,3 @@ impl ChunkingContext for NodeJsChunkingContext { }) } } - -#[turbo_tasks::value_impl] -impl EcmascriptChunkingContext for NodeJsChunkingContext {} diff --git a/crates/turbopack-resolve/src/ecmascript.rs b/crates/turbopack-resolve/src/ecmascript.rs index 9a51aeb567521..ef08b659de601 100644 --- a/crates/turbopack-resolve/src/ecmascript.rs +++ b/crates/turbopack-resolve/src/ecmascript.rs @@ -41,7 +41,10 @@ pub fn get_condition_maps( } #[turbo_tasks::function] -pub async fn apply_esm_specific_options(options: Vc) -> Result> { +pub async fn apply_esm_specific_options( + options: Vc, + reference_type: Value, +) -> Result> { let mut options: ResolveOptions = options.await?.clone_value(); // TODO set fully_specified when in strict ESM mode // options.fully_specified = true; @@ -49,6 +52,14 @@ pub async fn apply_esm_specific_options(options: Vc) -> Result>, ) -> Result> { let ty = Value::new(ReferenceType::EcmaScriptModules(ty.into_value())); - let options = apply_esm_specific_options(origin.resolve_options(ty.clone())) + let options = apply_esm_specific_options(origin.resolve_options(ty.clone()), ty.clone()) .resolve() .await?; specific_resolve(origin, request, options, ty, issue_severity, issue_source).await diff --git a/crates/turbopack-static/src/lib.rs b/crates/turbopack-static/src/lib.rs index 6f2a917628e5f..b135d951f7a06 100644 --- a/crates/turbopack-static/src/lib.rs +++ b/crates/turbopack-static/src/lib.rs @@ -14,7 +14,7 @@ pub mod fixed; pub mod output_asset; -use anyhow::{Context, Result}; +use anyhow::Result; use turbo_tasks::{ValueToString, Vc}; use turbopack_core::{ asset::{Asset, AssetContent}, @@ -30,7 +30,7 @@ use turbopack_css::embed::CssEmbed; use turbopack_ecmascript::{ chunk::{ EcmascriptChunkItem, EcmascriptChunkItemContent, EcmascriptChunkPlaceable, - EcmascriptChunkType, EcmascriptChunkingContext, EcmascriptExports, + EcmascriptChunkType, EcmascriptExports, }, utils::StringifyJs, }; @@ -94,12 +94,6 @@ impl ChunkableModule for StaticModuleAsset { self: Vc, chunking_context: Vc>, ) -> Result>> { - let chunking_context = - Vc::try_resolve_downcast::>(chunking_context) - .await? - .context( - "chunking context must impl EcmascriptChunkingContext to use StaticModuleAsset", - )?; Ok(Vc::upcast(ModuleChunkItem::cell(ModuleChunkItem { module: self, chunking_context, @@ -119,7 +113,7 @@ impl EcmascriptChunkPlaceable for StaticModuleAsset { #[turbo_tasks::value] struct ModuleChunkItem { module: Vc, - chunking_context: Vc>, + chunking_context: Vc>, static_asset: Vc, } @@ -162,7 +156,7 @@ impl ChunkItem for ModuleChunkItem { #[turbo_tasks::value_impl] impl EcmascriptChunkItem for ModuleChunkItem { #[turbo_tasks::function] - fn chunking_context(&self) -> Vc> { + fn chunking_context(&self) -> Vc> { self.chunking_context } diff --git a/crates/turbopack-tests/tests/snapshot/basic/async_chunk/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_4437c1._.js b/crates/turbopack-tests/tests/snapshot/basic/async_chunk/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_4437c1._.js index ea12418a687d6..6c83a63ecb906 100644 --- a/crates/turbopack-tests/tests/snapshot/basic/async_chunk/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_4437c1._.js +++ b/crates/turbopack-tests/tests/snapshot/basic/async_chunk/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_4437c1._.js @@ -1,11 +1,11 @@ (globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_4437c1._.js", { -"[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/shared.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__, m: module, e: exports, t: require }) { !function() { +"[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/shared.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { // shared package }.call(this) }), -"[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; __turbopack_esm__({}); @@ -20,7 +20,7 @@ __turbopack_require__("[project]/crates/turbopack-tests/tests/snapshot/basic/asy }); })()), -"[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/node_modules/bar/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/node_modules/bar/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; __turbopack_esm__({ diff --git a/crates/turbopack-tests/tests/snapshot/basic/async_chunk/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_4437c1._.js.map b/crates/turbopack-tests/tests/snapshot/basic/async_chunk/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_4437c1._.js.map index da57cec5054b8..ef464afe3c44a 100644 --- a/crates/turbopack-tests/tests/snapshot/basic/async_chunk/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_4437c1._.js.map +++ b/crates/turbopack-tests/tests/snapshot/basic/async_chunk/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_4437c1._.js.map @@ -2,10 +2,10 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/shared.js"],"sourcesContent":["// shared package\n"],"names":[],"mappings":"AAAA,iBAAiB"}}, + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/shared.js"],"sourcesContent":["// shared package\n"],"names":[],"mappings":"AAAA,iBAAiB"}}, {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 10, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/index.js"],"sourcesContent":["import { bar } from \"bar\";\nimport \"./shared\";\n\nbar(true);\n\nimport(\"./import\").then(({ foo }) => {\n foo(true);\n});\n"],"names":[],"mappings":";;;;;;AAGA,CAAA,GAAA,4MAAA,CAAA,MAAG,AAAD,EAAE;AAEJ,mKAAmB,IAAI,CAAC,CAAC,EAAE,GAAG,EAAE;IAC9B,IAAI;AACN"}}, + {"offset": {"line": 10, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/index.js"],"sourcesContent":["import { bar } from \"bar\";\nimport \"./shared\";\n\nbar(true);\n\nimport(\"./import\").then(({ foo }) => {\n foo(true);\n});\n"],"names":[],"mappings":";;;;;;AAGA,CAAA,GAAA,4MAAA,CAAA,MAAG,AAAD,EAAE;AAEJ,mKAAmB,IAAI,CAAC,CAAC,EAAE,GAAG,EAAE;IAC9B,IAAI;AACN"}}, {"offset": {"line": 20, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 25, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/node_modules/bar/index.js"],"sourcesContent":["export function bar(value) {\n console.assert(value);\n}\n"],"names":[],"mappings":";;;AAAO,SAAS,IAAI,KAAK;IACvB,QAAQ,MAAM,CAAC;AACjB"}}, + {"offset": {"line": 25, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/node_modules/bar/index.js"],"sourcesContent":["export function bar(value) {\n console.assert(value);\n}\n"],"names":[],"mappings":";;;AAAO,SAAS,IAAI,KAAK;IACvB,QAAQ,MAAM,CAAC;AACjB"}}, {"offset": {"line": 31, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/basic/async_chunk/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_aea885._.js b/crates/turbopack-tests/tests/snapshot/basic/async_chunk/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_aea885._.js index a47747b6e742e..fbd4b11f870cc 100644 --- a/crates/turbopack-tests/tests/snapshot/basic/async_chunk/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_aea885._.js +++ b/crates/turbopack-tests/tests/snapshot/basic/async_chunk/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_aea885._.js @@ -1,6 +1,6 @@ (globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_aea885._.js", { -"[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/import.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/import.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; __turbopack_esm__({}); @@ -15,7 +15,7 @@ var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests (0, __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2f$async_chunk$2f$input$2f$node_modules$2f$bar$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__["bar"])(true); })()), -"[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/node_modules/foo/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/node_modules/foo/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; __turbopack_esm__({ diff --git a/crates/turbopack-tests/tests/snapshot/basic/async_chunk/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_aea885._.js.map b/crates/turbopack-tests/tests/snapshot/basic/async_chunk/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_aea885._.js.map index 6b80abcf91f76..b85e2c92babb0 100644 --- a/crates/turbopack-tests/tests/snapshot/basic/async_chunk/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_aea885._.js.map +++ b/crates/turbopack-tests/tests/snapshot/basic/async_chunk/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_aea885._.js.map @@ -2,8 +2,8 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/import.js"],"sourcesContent":["import { foo } from \"foo\";\nimport { bar } from \"bar\";\nimport \"./shared\";\n\nfoo(true);\nbar(true);\n"],"names":[],"mappings":";;;;;;;;AAIA,CAAA,GAAA,4MAAA,CAAA,MAAG,AAAD,EAAE;AACJ,CAAA,GAAA,4MAAA,CAAA,MAAG,AAAD,EAAE"}}, + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/import.js"],"sourcesContent":["import { foo } from \"foo\";\nimport { bar } from \"bar\";\nimport \"./shared\";\n\nfoo(true);\nbar(true);\n"],"names":[],"mappings":";;;;;;;;AAIA,CAAA,GAAA,4MAAA,CAAA,MAAG,AAAD,EAAE;AACJ,CAAA,GAAA,4MAAA,CAAA,MAAG,AAAD,EAAE"}}, {"offset": {"line": 15, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 20, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/node_modules/foo/index.js"],"sourcesContent":["export function foo(value) {\n console.assert(value);\n}\n"],"names":[],"mappings":";;;AAAO,SAAS,IAAI,KAAK;IACvB,QAAQ,MAAM,CAAC;AACjB"}}, + {"offset": {"line": 20, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/node_modules/foo/index.js"],"sourcesContent":["export function foo(value) {\n console.assert(value);\n}\n"],"names":[],"mappings":";;;AAAO,SAAS,IAAI,KAAK;IACvB,QAAQ,MAAM,CAAC;AACjB"}}, {"offset": {"line": 26, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_build_input_baff26._.js.map b/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_build_input_baff26._.js.map index 68bcbcb96618e..ed74a49882995 100644 --- a/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_build_input_baff26._.js.map +++ b/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_build_input_baff26._.js.map @@ -2,10 +2,10 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/input/shared.js"],"sourcesContent":["// shared package\n"],"names":[],"mappings":"AAAA,iBAAiB"}}, + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/input/shared.js"],"sourcesContent":["// shared package\n"],"names":[],"mappings":"AAAA,iBAAiB"}}, {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 10, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/input/index.js"],"sourcesContent":["import { bar } from \"bar\";\nimport \"./shared\";\n\nbar(true);\n\nimport(\"./import\").then(({ foo }) => {\n foo(true);\n});\n"],"names":[],"mappings":";;;;;;AAGA,CAAA,GAAA,kNAAA,CAAA,MAAG,AAAD,EAAE;AAEJ,yKAAmB,IAAI,CAAC,CAAC,EAAE,GAAG,EAAE;IAC9B,IAAI;AACN"}}, + {"offset": {"line": 10, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/input/index.js"],"sourcesContent":["import { bar } from \"bar\";\nimport \"./shared\";\n\nbar(true);\n\nimport(\"./import\").then(({ foo }) => {\n foo(true);\n});\n"],"names":[],"mappings":";;;;;;AAGA,CAAA,GAAA,kNAAA,CAAA,MAAG,AAAD,EAAE;AAEJ,yKAAmB,IAAI,CAAC,CAAC,EAAE,GAAG,EAAE;IAC9B,IAAI;AACN"}}, {"offset": {"line": 20, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 25, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/input/node_modules/bar/index.js"],"sourcesContent":["export function bar(value) {\n console.assert(value);\n}\n"],"names":[],"mappings":";;;AAAO,SAAS,IAAI,KAAK;IACvB,QAAQ,MAAM,CAAC;AACjB"}}, + {"offset": {"line": 25, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/input/node_modules/bar/index.js"],"sourcesContent":["export function bar(value) {\n console.assert(value);\n}\n"],"names":[],"mappings":";;;AAAO,SAAS,IAAI,KAAK;IACvB,QAAQ,MAAM,CAAC;AACjB"}}, {"offset": {"line": 31, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_build_input_c494f8._.js.map b/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_build_input_c494f8._.js.map index a770b74d754a0..4d585a5aa6a9b 100644 --- a/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_build_input_c494f8._.js.map +++ b/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_build_input_c494f8._.js.map @@ -2,8 +2,8 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/input/import.js"],"sourcesContent":["import { foo } from \"foo\";\nimport { bar } from \"bar\";\nimport \"./shared\";\n\nfoo(true);\nbar(true);\n"],"names":[],"mappings":";;;;;;;;AAIA,CAAA,GAAA,kNAAA,CAAA,MAAG,AAAD,EAAE;AACJ,CAAA,GAAA,kNAAA,CAAA,MAAG,AAAD,EAAE"}}, + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/input/import.js"],"sourcesContent":["import { foo } from \"foo\";\nimport { bar } from \"bar\";\nimport \"./shared\";\n\nfoo(true);\nbar(true);\n"],"names":[],"mappings":";;;;;;;;AAIA,CAAA,GAAA,kNAAA,CAAA,MAAG,AAAD,EAAE;AACJ,CAAA,GAAA,kNAAA,CAAA,MAAG,AAAD,EAAE"}}, {"offset": {"line": 15, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 20, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/input/node_modules/foo/index.js"],"sourcesContent":["export function foo(value) {\n console.assert(value);\n}\n"],"names":[],"mappings":";;;AAAO,SAAS,IAAI,KAAK;IACvB,QAAQ,MAAM,CAAC;AACjB"}}, + {"offset": {"line": 20, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/input/node_modules/foo/index.js"],"sourcesContent":["export function foo(value) {\n console.assert(value);\n}\n"],"names":[],"mappings":";;;AAAO,SAAS,IAAI,KAAK;IACvB,QAAQ,MAAM,CAAC;AACjB"}}, {"offset": {"line": 26, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/basic/chunked/output/crates_turbopack-tests_tests_snapshot_basic_chunked_input_09b9a1._.js b/crates/turbopack-tests/tests/snapshot/basic/chunked/output/crates_turbopack-tests_tests_snapshot_basic_chunked_input_09b9a1._.js index 65c014415ac64..589b94493d7a1 100644 --- a/crates/turbopack-tests/tests/snapshot/basic/chunked/output/crates_turbopack-tests_tests_snapshot_basic_chunked_input_09b9a1._.js +++ b/crates/turbopack-tests/tests/snapshot/basic/chunked/output/crates_turbopack-tests_tests_snapshot_basic_chunked_input_09b9a1._.js @@ -1,6 +1,6 @@ (globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_basic_chunked_input_09b9a1._.js", { -"[project]/crates/turbopack-tests/tests/snapshot/basic/chunked/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/basic/chunked/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; __turbopack_esm__({}); @@ -10,7 +10,7 @@ var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests (0, __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2f$chunked$2f$input$2f$node_modules$2f$foo$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__["foo"])(true); })()), -"[project]/crates/turbopack-tests/tests/snapshot/basic/chunked/input/node_modules/foo/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/basic/chunked/input/node_modules/foo/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; __turbopack_esm__({ diff --git a/crates/turbopack-tests/tests/snapshot/basic/chunked/output/crates_turbopack-tests_tests_snapshot_basic_chunked_input_09b9a1._.js.map b/crates/turbopack-tests/tests/snapshot/basic/chunked/output/crates_turbopack-tests_tests_snapshot_basic_chunked_input_09b9a1._.js.map index 2be67f8d0f75b..ffb4ceca543ef 100644 --- a/crates/turbopack-tests/tests/snapshot/basic/chunked/output/crates_turbopack-tests_tests_snapshot_basic_chunked_input_09b9a1._.js.map +++ b/crates/turbopack-tests/tests/snapshot/basic/chunked/output/crates_turbopack-tests_tests_snapshot_basic_chunked_input_09b9a1._.js.map @@ -2,8 +2,8 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/basic/chunked/input/index.js"],"sourcesContent":["import { foo } from \"foo\";\n\nfoo(true);\n"],"names":[],"mappings":";;;;AAEA,CAAA,GAAA,wMAAA,CAAA,MAAG,AAAD,EAAE"}}, + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic/chunked/input/index.js"],"sourcesContent":["import { foo } from \"foo\";\n\nfoo(true);\n"],"names":[],"mappings":";;;;AAEA,CAAA,GAAA,wMAAA,CAAA,MAAG,AAAD,EAAE"}}, {"offset": {"line": 10, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 15, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/basic/chunked/input/node_modules/foo/index.js"],"sourcesContent":["export function foo(value) {\n console.assert(value);\n}\n"],"names":[],"mappings":";;;AAAO,SAAS,IAAI,KAAK;IACvB,QAAQ,MAAM,CAAC;AACjB"}}, + {"offset": {"line": 15, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic/chunked/input/node_modules/foo/index.js"],"sourcesContent":["export function foo(value) {\n console.assert(value);\n}\n"],"names":[],"mappings":";;;AAAO,SAAS,IAAI,KAAK;IACvB,QAAQ,MAAM,CAAC;AACjB"}}, {"offset": {"line": 21, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/basic/ecmascript_minify/output/crates_turbopack-tests_tests_snapshot_basic_ecmascript_minify_input_index_dc5b16.js.map b/crates/turbopack-tests/tests/snapshot/basic/ecmascript_minify/output/crates_turbopack-tests_tests_snapshot_basic_ecmascript_minify_input_index_dc5b16.js.map index 059d834b6041f..f5cab8e9ada88 100644 --- a/crates/turbopack-tests/tests/snapshot/basic/ecmascript_minify/output/crates_turbopack-tests_tests_snapshot_basic_ecmascript_minify_input_index_dc5b16.js.map +++ b/crates/turbopack-tests/tests/snapshot/basic/ecmascript_minify/output/crates_turbopack-tests_tests_snapshot_basic_ecmascript_minify_input_index_dc5b16.js.map @@ -2,6 +2,6 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 0, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/basic/ecmascript_minify/input/index.js"],"sourcesContent":["const inlined = 3;\nconst message = getMessage();\n\nconsole.log(\"Hello,\" + \" world!\", inlined, message);\nconsole.log(message);\n\nfunction getMessage() {\n return \"Hello\";\n}\n"],"names":[],"mappings":"qOACA,IAAM,EAMG,QAJT,QAAQ,GAAG,CAAC,gBAHI,EAG2B,GAC3C,QAAQ,GAAG,CAAC"}}, + {"offset": {"line": 0, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic/ecmascript_minify/input/index.js"],"sourcesContent":["const inlined = 3;\nconst message = getMessage();\n\nconsole.log(\"Hello,\" + \" world!\", inlined, message);\nconsole.log(message);\n\nfunction getMessage() {\n return \"Hello\";\n}\n"],"names":[],"mappings":"qOACA,IAAM,EAMG,QAJT,QAAQ,GAAG,CAAC,gBAHI,EAG2B,GAC3C,QAAQ,GAAG,CAAC"}}, {"offset": {"line": 0, "column": 306}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/basic/shebang/output/crates_turbopack-tests_tests_snapshot_basic_shebang_input_a87633._.js b/crates/turbopack-tests/tests/snapshot/basic/shebang/output/crates_turbopack-tests_tests_snapshot_basic_shebang_input_a87633._.js index 4299ade38bc8d..09a17c27ac064 100644 --- a/crates/turbopack-tests/tests/snapshot/basic/shebang/output/crates_turbopack-tests_tests_snapshot_basic_shebang_input_a87633._.js +++ b/crates/turbopack-tests/tests/snapshot/basic/shebang/output/crates_turbopack-tests_tests_snapshot_basic_shebang_input_a87633._.js @@ -1,6 +1,6 @@ (globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_basic_shebang_input_a87633._.js", { -"[project]/crates/turbopack-tests/tests/snapshot/basic/shebang/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/basic/shebang/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; __turbopack_esm__({}); @@ -10,7 +10,7 @@ var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests (0, __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2f$shebang$2f$input$2f$node_modules$2f$foo$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__["foo"])(true); })()), -"[project]/crates/turbopack-tests/tests/snapshot/basic/shebang/input/node_modules/foo/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/basic/shebang/input/node_modules/foo/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; __turbopack_esm__({ diff --git a/crates/turbopack-tests/tests/snapshot/basic/shebang/output/crates_turbopack-tests_tests_snapshot_basic_shebang_input_a87633._.js.map b/crates/turbopack-tests/tests/snapshot/basic/shebang/output/crates_turbopack-tests_tests_snapshot_basic_shebang_input_a87633._.js.map index 3570287a25929..d2dbe585a12f0 100644 --- a/crates/turbopack-tests/tests/snapshot/basic/shebang/output/crates_turbopack-tests_tests_snapshot_basic_shebang_input_a87633._.js.map +++ b/crates/turbopack-tests/tests/snapshot/basic/shebang/output/crates_turbopack-tests_tests_snapshot_basic_shebang_input_a87633._.js.map @@ -2,8 +2,8 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/basic/shebang/input/index.js"],"sourcesContent":["#!/usr/bin/env node\n\nimport { foo } from \"foo\";\n\nfoo(true);\n"],"names":[],"mappings":";;;;AAIA,CAAA,GAAA,wMAAA,CAAA,MAAG,AAAD,EAAE"}}, + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic/shebang/input/index.js"],"sourcesContent":["#!/usr/bin/env node\n\nimport { foo } from \"foo\";\n\nfoo(true);\n"],"names":[],"mappings":";;;;AAIA,CAAA,GAAA,wMAAA,CAAA,MAAG,AAAD,EAAE"}}, {"offset": {"line": 10, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 15, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/basic/shebang/input/node_modules/foo/index.js"],"sourcesContent":["#!/usr/bin/env node\n\nexport function foo(value) {\n console.assert(value);\n}\n"],"names":[],"mappings":";;;AAEO,SAAS,IAAI,KAAK;IACvB,QAAQ,MAAM,CAAC;AACjB"}}, + {"offset": {"line": 15, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic/shebang/input/node_modules/foo/index.js"],"sourcesContent":["#!/usr/bin/env node\n\nexport function foo(value) {\n console.assert(value);\n}\n"],"names":[],"mappings":";;;AAEO,SAAS,IAAI,KAAK;IACvB,QAAQ,MAAM,CAAC;AACjB"}}, {"offset": {"line": 21, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/basic/top-level-await/output/crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_3adb52._.js b/crates/turbopack-tests/tests/snapshot/basic/top-level-await/output/crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_3adb52._.js index 8203bd4f61d2c..48d673772bf3b 100644 --- a/crates/turbopack-tests/tests/snapshot/basic/top-level-await/output/crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_3adb52._.js +++ b/crates/turbopack-tests/tests/snapshot/basic/top-level-await/output/crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_3adb52._.js @@ -1,6 +1,6 @@ (globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_3adb52._.js", { -"[project]/crates/turbopack-tests/tests/snapshot/basic/top-level-await/input/Actions.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/basic/top-level-await/input/Actions.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; // import() doesn't care about whether a module is an async module or not @@ -22,7 +22,7 @@ const AlternativeCreateUserAction = async (name)=>{ // except in rare cases. It will import modules sequentially. })()), -"[project]/crates/turbopack-tests/tests/snapshot/basic/top-level-await/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/basic/top-level-await/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; __turbopack_esm__({}); diff --git a/crates/turbopack-tests/tests/snapshot/basic/top-level-await/output/crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_3adb52._.js.map b/crates/turbopack-tests/tests/snapshot/basic/top-level-await/output/crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_3adb52._.js.map index 67a00632c3ad3..f8e6630a057db 100644 --- a/crates/turbopack-tests/tests/snapshot/basic/top-level-await/output/crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_3adb52._.js.map +++ b/crates/turbopack-tests/tests/snapshot/basic/top-level-await/output/crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_3adb52._.js.map @@ -2,8 +2,8 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/basic/top-level-await/input/Actions.js"],"sourcesContent":["// import() doesn't care about whether a module is an async module or not\nconst UserApi = import(\"./UserAPI.js\");\n\nexport const CreateUserAction = async (name) => {\n console.log(\"Creating user\", name);\n // These are normal awaits, because they are in an async function\n const { createUser } = await UserApi;\n await createUser(name);\n};\n\n// You can place import() where you like\n// Placing it at top-level will start loading and evaluating on\n// module evaluation.\n// see CreateUserAction above\n// Here: Connecting to the DB starts when the application starts\n// Placing it inside of an (async) function will start loading\n// and evaluating when the function is called for the first time\n// which basically makes it lazy-loaded.\n// see AlternativeCreateUserAction below\n// Here: Connecting to the DB starts when AlternativeCreateUserAction\n// is called\nexport const AlternativeCreateUserAction = async (name) => {\n const { createUser } = await import(\"./UserAPI.js\");\n await createUser(name);\n};\n\n// Note: Using await import() at top-level doesn't make much sense\n// except in rare cases. It will import modules sequentially.\n"],"names":[],"mappings":"AAAA,yEAAyE;;;;;AACzE,MAAM;AAEC,MAAM,mBAAmB,OAAO;IACrC,QAAQ,GAAG,CAAC,iBAAiB;IAC7B,iEAAiE;IACjE,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM;IAC7B,MAAM,WAAW;AACnB;AAaO,MAAM,8BAA8B,OAAO;IAChD,MAAM,EAAE,UAAU,EAAE,GAAG;IACvB,MAAM,WAAW;AACnB,GAEA,kEAAkE;CAClE,mEAAmE"}}, + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic/top-level-await/input/Actions.js"],"sourcesContent":["// import() doesn't care about whether a module is an async module or not\nconst UserApi = import(\"./UserAPI.js\");\n\nexport const CreateUserAction = async (name) => {\n console.log(\"Creating user\", name);\n // These are normal awaits, because they are in an async function\n const { createUser } = await UserApi;\n await createUser(name);\n};\n\n// You can place import() where you like\n// Placing it at top-level will start loading and evaluating on\n// module evaluation.\n// see CreateUserAction above\n// Here: Connecting to the DB starts when the application starts\n// Placing it inside of an (async) function will start loading\n// and evaluating when the function is called for the first time\n// which basically makes it lazy-loaded.\n// see AlternativeCreateUserAction below\n// Here: Connecting to the DB starts when AlternativeCreateUserAction\n// is called\nexport const AlternativeCreateUserAction = async (name) => {\n const { createUser } = await import(\"./UserAPI.js\");\n await createUser(name);\n};\n\n// Note: Using await import() at top-level doesn't make much sense\n// except in rare cases. It will import modules sequentially.\n"],"names":[],"mappings":"AAAA,yEAAyE;;;;;AACzE,MAAM;AAEC,MAAM,mBAAmB,OAAO;IACrC,QAAQ,GAAG,CAAC,iBAAiB;IAC7B,iEAAiE;IACjE,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM;IAC7B,MAAM,WAAW;AACnB;AAaO,MAAM,8BAA8B,OAAO;IAChD,MAAM,EAAE,UAAU,EAAE,GAAG;IACvB,MAAM,WAAW;AACnB,GAEA,kEAAkE;CAClE,mEAAmE"}}, {"offset": {"line": 22, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 27, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/basic/top-level-await/input/index.js"],"sourcesContent":["import { CreateUserAction } from \"./Actions.js\";\n\n(async () => {\n await CreateUserAction(\"John\");\n console.log(\"created user John\");\n})();\n"],"names":[],"mappings":";;;;AAEA,CAAC;IACC,MAAM,CAAA,GAAA,iMAAA,CAAA,mBAAgB,AAAD,EAAE;IACvB,QAAQ,GAAG,CAAC;AACd,CAAC"}}, + {"offset": {"line": 27, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic/top-level-await/input/index.js"],"sourcesContent":["import { CreateUserAction } from \"./Actions.js\";\n\n(async () => {\n await CreateUserAction(\"John\");\n console.log(\"created user John\");\n})();\n"],"names":[],"mappings":";;;;AAEA,CAAC;IACC,MAAM,CAAA,GAAA,iMAAA,CAAA,mBAAgB,AAAD,EAAE;IACvB,QAAQ,GAAG,CAAC;AACd,CAAC"}}, {"offset": {"line": 35, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/basic/top-level-await/output/crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_e71653._.js b/crates/turbopack-tests/tests/snapshot/basic/top-level-await/output/crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_e71653._.js index 535f8981ea638..70d45d918335d 100644 --- a/crates/turbopack-tests/tests/snapshot/basic/top-level-await/output/crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_e71653._.js +++ b/crates/turbopack-tests/tests/snapshot/basic/top-level-await/output/crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_e71653._.js @@ -1,6 +1,6 @@ (globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_e71653._.js", { -"[project]/crates/turbopack-tests/tests/snapshot/basic/top-level-await/input/db-connection.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, a: __turbopack_async_module__, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/basic/top-level-await/input/db-connection.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, a: __turbopack_async_module__ }) => (() => { "use strict"; __turbopack_async_module__(async (__turbopack_handle_async_dependencies__, __turbopack_async_result__) => { try { @@ -26,7 +26,7 @@ const close = ()=>{ __turbopack_async_result__(); } catch(e) { __turbopack_async_result__(e); } }, true); })()), -"[project]/crates/turbopack-tests/tests/snapshot/basic/top-level-await/input/UserAPI.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, a: __turbopack_async_module__, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/basic/top-level-await/input/UserAPI.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, a: __turbopack_async_module__ }) => (() => { "use strict"; __turbopack_async_module__(async (__turbopack_handle_async_dependencies__, __turbopack_async_result__) => { try { diff --git a/crates/turbopack-tests/tests/snapshot/basic/top-level-await/output/crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_e71653._.js.map b/crates/turbopack-tests/tests/snapshot/basic/top-level-await/output/crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_e71653._.js.map index 6075cc12abd45..f6a0fa1027202 100644 --- a/crates/turbopack-tests/tests/snapshot/basic/top-level-await/output/crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_e71653._.js.map +++ b/crates/turbopack-tests/tests/snapshot/basic/top-level-await/output/crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_e71653._.js.map @@ -2,8 +2,8 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 6, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/basic/top-level-await/input/db-connection.js"],"sourcesContent":["const connectToDB = async (url) => {\n console.log(\"connecting to db\", url);\n await new Promise((r) => setTimeout(r, 1000));\n};\n\n// This is a top-level-await\nawait connectToDB(\"my-sql://example.com\");\n\nexport const dbCall = async (data) => {\n console.log(\"dbCall\", data);\n // This is a normal await, because it's in an async function\n await new Promise((r) => setTimeout(r, 100));\n return \"fake data\";\n};\n\nexport const close = () => {\n console.log(\"closes the DB connection\");\n};\n"],"names":[],"mappings":";;;;AAAA,MAAM,cAAc,OAAO;IACzB,QAAQ,GAAG,CAAC,oBAAoB;IAChC,MAAM,IAAI,QAAQ,CAAC,IAAM,WAAW,GAAG;AACzC;AAEA,4BAA4B;AAC5B,MAAM,YAAY;AAEX,MAAM,SAAS,OAAO;IAC3B,QAAQ,GAAG,CAAC,UAAU;IACtB,4DAA4D;IAC5D,MAAM,IAAI,QAAQ,CAAC,IAAM,WAAW,GAAG;IACvC,OAAO;AACT;AAEO,MAAM,QAAQ;IACnB,QAAQ,GAAG,CAAC;AACd"}}, + {"offset": {"line": 6, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic/top-level-await/input/db-connection.js"],"sourcesContent":["const connectToDB = async (url) => {\n console.log(\"connecting to db\", url);\n await new Promise((r) => setTimeout(r, 1000));\n};\n\n// This is a top-level-await\nawait connectToDB(\"my-sql://example.com\");\n\nexport const dbCall = async (data) => {\n console.log(\"dbCall\", data);\n // This is a normal await, because it's in an async function\n await new Promise((r) => setTimeout(r, 100));\n return \"fake data\";\n};\n\nexport const close = () => {\n console.log(\"closes the DB connection\");\n};\n"],"names":[],"mappings":";;;;AAAA,MAAM,cAAc,OAAO;IACzB,QAAQ,GAAG,CAAC,oBAAoB;IAChC,MAAM,IAAI,QAAQ,CAAC,IAAM,WAAW,GAAG;AACzC;AAEA,4BAA4B;AAC5B,MAAM,YAAY;AAEX,MAAM,SAAS,OAAO;IAC3B,QAAQ,GAAG,CAAC,UAAU;IACtB,4DAA4D;IAC5D,MAAM,IAAI,QAAQ,CAAC,IAAM,WAAW,GAAG;IACvC,OAAO;AACT;AAEO,MAAM,QAAQ;IACnB,QAAQ,GAAG,CAAC;AACd"}}, {"offset": {"line": 25, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 32, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/basic/top-level-await/input/UserAPI.js"],"sourcesContent":["import { dbCall } from \"./db-connection.js\";\n\nexport const createUser = async (name) => {\n const command = `CREATE USER ${name}`;\n // This is a normal await, because it's in an async function\n await dbCall({ command });\n};\n"],"names":[],"mappings":";;;;;;;;;;AAEO,MAAM,aAAa,OAAO;IAC/B,MAAM,UAAU,CAAC,YAAY,EAAE,KAAK,CAAC;IACrC,4DAA4D;IAC5D,MAAM,CAAA,GAAA,0MAAA,CAAA,SAAM,AAAD,EAAE;QAAE;IAAQ;AACzB"}}, + {"offset": {"line": 32, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic/top-level-await/input/UserAPI.js"],"sourcesContent":["import { dbCall } from \"./db-connection.js\";\n\nexport const createUser = async (name) => {\n const command = `CREATE USER ${name}`;\n // This is a normal await, because it's in an async function\n await dbCall({ command });\n};\n"],"names":[],"mappings":";;;;;;;;;;AAEO,MAAM,aAAa,OAAO;IAC/B,MAAM,UAAU,CAAC,YAAY,EAAE,KAAK,CAAC;IACrC,4DAA4D;IAC5D,MAAM,CAAA,GAAA,0MAAA,CAAA,SAAM,AAAD,EAAE;QAAE;IAAQ;AACzB"}}, {"offset": {"line": 49, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/comptime/define/output/crates_turbopack-tests_tests_snapshot_comptime_define_input_index_49857f.js b/crates/turbopack-tests/tests/snapshot/comptime/define/output/crates_turbopack-tests_tests_snapshot_comptime_define_input_index_49857f.js index 105c42521900f..5ba3ec6877d0c 100644 --- a/crates/turbopack-tests/tests/snapshot/comptime/define/output/crates_turbopack-tests_tests_snapshot_comptime_define_input_index_49857f.js +++ b/crates/turbopack-tests/tests/snapshot/comptime/define/output/crates_turbopack-tests_tests_snapshot_comptime_define_input_index_49857f.js @@ -1,6 +1,6 @@ (globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_comptime_define_input_index_49857f.js", { -"[project]/crates/turbopack-tests/tests/snapshot/comptime/define/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__, m: module, e: exports, t: require }) { !function() { +"[project]/crates/turbopack-tests/tests/snapshot/comptime/define/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { if ("TURBOPACK compile-time truthy", 1) { console.log('DEFINED_VALUE'); diff --git a/crates/turbopack-tests/tests/snapshot/comptime/define/output/crates_turbopack-tests_tests_snapshot_comptime_define_input_index_49857f.js.map b/crates/turbopack-tests/tests/snapshot/comptime/define/output/crates_turbopack-tests_tests_snapshot_comptime_define_input_index_49857f.js.map index 98c3711d7c1cc..b469b41139cc4 100644 --- a/crates/turbopack-tests/tests/snapshot/comptime/define/output/crates_turbopack-tests_tests_snapshot_comptime_define_input_index_49857f.js.map +++ b/crates/turbopack-tests/tests/snapshot/comptime/define/output/crates_turbopack-tests_tests_snapshot_comptime_define_input_index_49857f.js.map @@ -2,6 +2,6 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/comptime/define/input/index.js"],"sourcesContent":["if (DEFINED_VALUE) {\n console.log('DEFINED_VALUE');\n}\n\nif (DEFINED_TRUE) {\n console.log('DEFINED_VALUE');\n}\n\nif (A.VERY.LONG.DEFINED.VALUE) {\n console.log('A.VERY.LONG.DEFINED.VALUE');\n}\n\nif (process.env.NODE_ENV) {\n console.log('something');\n}\n\nif (process.env.NODE_ENV === 'production') {\n console.log('production');\n}\n\nvar p = process;\n\nconsole.log(A.VERY.LONG.DEFINED.VALUE);\nconsole.log(DEFINED_VALUE);\nconsole.log(p.env.NODE_ENV);\n\nif (p.env.NODE_ENV === 'production') {\n console.log('production');\n}\n\np.env.NODE_ENV == 'production' ? console.log('production') : console.log('development');\n\n// TODO short-circuit is not implemented yet\np.env.NODE_ENV != 'production' && console.log('development');\np.env.NODE_ENV == 'production' && console.log('production');\n"],"names":[],"mappings":"AAAA,wCAAmB;IACjB,QAAQ,GAAG,CAAC;AACd;AAEA,wCAAkB;IAChB,QAAQ,GAAG,CAAC;AACd;AAEA,iEAA+B;IAC7B,QAAQ,GAAG,CAAC;AACd;AAEA,wCAA0B;IACxB,QAAQ,GAAG,CAAC;AACd;AAEA;;;AAIA,IAAI,IAAI;AAER,QAAQ,GAAG;AACX,QAAQ,GAAG;AACX,QAAQ,GAAG;AAEX;;;AAIA,6EAA6D,QAAQ,GAAG,CAAC;AAEzE,4CAA4C;AAC5C,mDAAkB,gBAAgB,QAAQ,GAAG,CAAC;AAC9C,mDAAkB,gBAAgB,QAAQ,GAAG,CAAC"}}, + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/comptime/define/input/index.js"],"sourcesContent":["if (DEFINED_VALUE) {\n console.log('DEFINED_VALUE');\n}\n\nif (DEFINED_TRUE) {\n console.log('DEFINED_VALUE');\n}\n\nif (A.VERY.LONG.DEFINED.VALUE) {\n console.log('A.VERY.LONG.DEFINED.VALUE');\n}\n\nif (process.env.NODE_ENV) {\n console.log('something');\n}\n\nif (process.env.NODE_ENV === 'production') {\n console.log('production');\n}\n\nvar p = process;\n\nconsole.log(A.VERY.LONG.DEFINED.VALUE);\nconsole.log(DEFINED_VALUE);\nconsole.log(p.env.NODE_ENV);\n\nif (p.env.NODE_ENV === 'production') {\n console.log('production');\n}\n\np.env.NODE_ENV == 'production' ? console.log('production') : console.log('development');\n\n// TODO short-circuit is not implemented yet\np.env.NODE_ENV != 'production' && console.log('development');\np.env.NODE_ENV == 'production' && console.log('production');\n"],"names":[],"mappings":"AAAA,wCAAmB;IACjB,QAAQ,GAAG,CAAC;AACd;AAEA,wCAAkB;IAChB,QAAQ,GAAG,CAAC;AACd;AAEA,iEAA+B;IAC7B,QAAQ,GAAG,CAAC;AACd;AAEA,wCAA0B;IACxB,QAAQ,GAAG,CAAC;AACd;AAEA;;;AAIA,IAAI,IAAI;AAER,QAAQ,GAAG;AACX,QAAQ,GAAG;AACX,QAAQ,GAAG;AAEX;;;AAIA,6EAA6D,QAAQ,GAAG,CAAC;AAEzE,4CAA4C;AAC5C,mDAAkB,gBAAgB,QAAQ,GAAG,CAAC;AAC9C,mDAAkB,gBAAgB,QAAQ,GAAG,CAAC"}}, {"offset": {"line": 30, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/output/a587c_tests_snapshot_css_absolute-uri-import_input_withduplicateurl_d96429.css.map b/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/output/a587c_tests_snapshot_css_absolute-uri-import_input_withduplicateurl_d96429.css.map index b2ff5496fa6fa..abfbc2588c793 100644 --- a/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/output/a587c_tests_snapshot_css_absolute-uri-import_input_withduplicateurl_d96429.css.map +++ b/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/output/a587c_tests_snapshot_css_absolute-uri-import_input_withduplicateurl_d96429.css.map @@ -2,6 +2,6 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/input/withduplicateurl.css"],"sourcesContent":["/* This should not be duplicated */\n@import \"https://example.com/stylesheet1.css\";\n\n.bar {\n background-color:green;\n}\n"],"names":[],"mappings":"AAGA"}}, + {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/input/withduplicateurl.css"],"sourcesContent":["/* This should not be duplicated */\n@import \"https://example.com/stylesheet1.css\";\n\n.bar {\n background-color:green;\n}\n"],"names":[],"mappings":"AAGA"}}, {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/output/crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_90d01b._.css.map b/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/output/crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_90d01b._.css.map index 1bcb6d33d6b58..2d9ddce40031b 100644 --- a/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/output/crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_90d01b._.css.map +++ b/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/output/crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_90d01b._.css.map @@ -2,10 +2,10 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/input/other.css"],"sourcesContent":[".foo {\n background-color: red;\n}\n"],"names":[],"mappings":"AAAA"}}, + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/input/other.css"],"sourcesContent":[".foo {\n background-color: red;\n}\n"],"names":[],"mappings":"AAAA"}}, {"offset": {"line": 7, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 10, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/input/withduplicateurl.css"],"sourcesContent":["/* This should not be duplicated */\n@import \"https://example.com/stylesheet1.css\";\n\n.bar {\n background-color:green;\n}\n"],"names":[],"mappings":"AAGA"}}, + {"offset": {"line": 10, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/input/withduplicateurl.css"],"sourcesContent":["/* This should not be duplicated */\n@import \"https://example.com/stylesheet1.css\";\n\n.bar {\n background-color:green;\n}\n"],"names":[],"mappings":"AAGA"}}, {"offset": {"line": 13, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 16, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/input/index.css"],"sourcesContent":["@import \"https://example.com/stylesheet1.css\";\n@import \"https://example.com/withquote\\\".css\";\n@import \"./other.css\";\n@import \"./withduplicateurl.css\";\n@import url(\"https://example.com/stylesheet2.css\");\n\nbody {\n background-color: blue;\n}\n"],"names":[],"mappings":"AAMA"}}, + {"offset": {"line": 16, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/input/index.css"],"sourcesContent":["@import \"https://example.com/stylesheet1.css\";\n@import \"https://example.com/withquote\\\".css\";\n@import \"./other.css\";\n@import \"./withduplicateurl.css\";\n@import url(\"https://example.com/stylesheet2.css\");\n\nbody {\n background-color: blue;\n}\n"],"names":[],"mappings":"AAMA"}}, {"offset": {"line": 19, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/output/crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_index_0e8055.js b/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/output/crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_index_0e8055.js index b126bb6432a7f..ba94954aa8b20 100644 --- a/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/output/crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_index_0e8055.js +++ b/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/output/crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_index_0e8055.js @@ -1,6 +1,6 @@ (globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_index_0e8055.js", { -"[project]/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__, m: module, e: exports, t: require }) { !function() { +"[project]/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { __turbopack_esm__({}); ; diff --git a/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/output/crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_index_7d7e1c.css.map b/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/output/crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_index_7d7e1c.css.map index a5b87cd75652e..ea443b3ac32d8 100644 --- a/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/output/crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_index_7d7e1c.css.map +++ b/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/output/crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_index_7d7e1c.css.map @@ -2,6 +2,6 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/input/index.css"],"sourcesContent":["@import \"https://example.com/stylesheet1.css\";\n@import \"https://example.com/withquote\\\".css\";\n@import \"./other.css\";\n@import \"./withduplicateurl.css\";\n@import url(\"https://example.com/stylesheet2.css\");\n\nbody {\n background-color: blue;\n}\n"],"names":[],"mappings":"AAMA"}}, + {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/input/index.css"],"sourcesContent":["@import \"https://example.com/stylesheet1.css\";\n@import \"https://example.com/withquote\\\".css\";\n@import \"./other.css\";\n@import \"./withduplicateurl.css\";\n@import url(\"https://example.com/stylesheet2.css\");\n\nbody {\n background-color: blue;\n}\n"],"names":[],"mappings":"AAMA"}}, {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/output/crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_other_d96429.css.map b/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/output/crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_other_d96429.css.map index 2f2cc99e066b4..0bd0381fd9a54 100644 --- a/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/output/crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_other_d96429.css.map +++ b/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/output/crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_other_d96429.css.map @@ -2,6 +2,6 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/input/other.css"],"sourcesContent":[".foo {\n background-color: red;\n}\n"],"names":[],"mappings":"AAAA"}}, + {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/input/other.css"],"sourcesContent":[".foo {\n background-color: red;\n}\n"],"names":[],"mappings":"AAAA"}}, {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_86e399._.css.map b/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_86e399._.css.map index 86e36864db836..0dc122cbe28b7 100644 --- a/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_86e399._.css.map +++ b/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_86e399._.css.map @@ -2,14 +2,14 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/c.css"],"sourcesContent":[".imported {\n color: red;\n}\n"],"names":[],"mappings":"AAAA"}}, + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/c.css"],"sourcesContent":[".imported {\n color: red;\n}\n"],"names":[],"mappings":"AAAA"}}, {"offset": {"line": 7, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 16, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/c.css"],"sourcesContent":[".imported {\n color: red;\n}\n"],"names":[],"mappings":"AAAA"}}, + {"offset": {"line": 16, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/c.css"],"sourcesContent":[".imported {\n color: red;\n}\n"],"names":[],"mappings":"AAAA"}}, {"offset": {"line": 19, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 28, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/b.css"],"sourcesContent":["@import url(\"./c.css\") layer(foo) (orientation: landscape);\n@import url(\"./c.css\") layer(bar) (orientation: portrait);\n\n.imported {\n color: orange;\n}\n"],"names":[],"mappings":"AAGA"}}, + {"offset": {"line": 28, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/b.css"],"sourcesContent":["@import url(\"./c.css\") layer(foo) (orientation: landscape);\n@import url(\"./c.css\") layer(bar) (orientation: portrait);\n\n.imported {\n color: orange;\n}\n"],"names":[],"mappings":"AAGA"}}, {"offset": {"line": 31, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 40, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/a.css"],"sourcesContent":["@import url(\"./b.css\") supports(font-format(woff2));\n\n.imported {\n color: cyan;\n}\n"],"names":[],"mappings":"AAEA"}}, + {"offset": {"line": 40, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/a.css"],"sourcesContent":["@import url(\"./b.css\") supports(font-format(woff2));\n\n.imported {\n color: cyan;\n}\n"],"names":[],"mappings":"AAEA"}}, {"offset": {"line": 43, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 49, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/style.css"],"sourcesContent":["@import url(\"./a.css\") layer(layer) supports(not(display: inline-grid)) print;\n\n.style {\n color: yellow;\n}\n"],"names":[],"mappings":"AAEA"}}, + {"offset": {"line": 49, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/style.css"],"sourcesContent":["@import url(\"./a.css\") layer(layer) supports(not(display: inline-grid)) print;\n\n.style {\n color: yellow;\n}\n"],"names":[],"mappings":"AAEA"}}, {"offset": {"line": 52, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_a_bf62fc.css.map b/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_a_bf62fc.css.map index c9199db068cb4..7604512ec73ba 100644 --- a/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_a_bf62fc.css.map +++ b/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_a_bf62fc.css.map @@ -2,6 +2,6 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/a.css"],"sourcesContent":["@import url(\"./b.css\") supports(font-format(woff2));\n\n.imported {\n color: cyan;\n}\n"],"names":[],"mappings":"AAEA"}}, + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/a.css"],"sourcesContent":["@import url(\"./b.css\") supports(font-format(woff2));\n\n.imported {\n color: cyan;\n}\n"],"names":[],"mappings":"AAEA"}}, {"offset": {"line": 7, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_b_dc1da6.css.map b/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_b_dc1da6.css.map index 93905acf96f48..bce1e5b1034ac 100644 --- a/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_b_dc1da6.css.map +++ b/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_b_dc1da6.css.map @@ -2,6 +2,6 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/b.css"],"sourcesContent":["@import url(\"./c.css\") layer(foo) (orientation: landscape);\n@import url(\"./c.css\") layer(bar) (orientation: portrait);\n\n.imported {\n color: orange;\n}\n"],"names":[],"mappings":"AAGA"}}, + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/b.css"],"sourcesContent":["@import url(\"./c.css\") layer(foo) (orientation: landscape);\n@import url(\"./c.css\") layer(bar) (orientation: portrait);\n\n.imported {\n color: orange;\n}\n"],"names":[],"mappings":"AAGA"}}, {"offset": {"line": 7, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_c_163c6a.css.map b/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_c_163c6a.css.map index ea61221d372f7..0dee96844eed0 100644 --- a/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_c_163c6a.css.map +++ b/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_c_163c6a.css.map @@ -2,6 +2,6 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/c.css"],"sourcesContent":[".imported {\n color: red;\n}\n"],"names":[],"mappings":"AAAA"}}, + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/c.css"],"sourcesContent":[".imported {\n color: red;\n}\n"],"names":[],"mappings":"AAAA"}}, {"offset": {"line": 7, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_c_823b12.css.map b/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_c_823b12.css.map index ea61221d372f7..0dee96844eed0 100644 --- a/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_c_823b12.css.map +++ b/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_c_823b12.css.map @@ -2,6 +2,6 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/c.css"],"sourcesContent":[".imported {\n color: red;\n}\n"],"names":[],"mappings":"AAAA"}}, + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/c.css"],"sourcesContent":[".imported {\n color: red;\n}\n"],"names":[],"mappings":"AAAA"}}, {"offset": {"line": 7, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_index_356166.js b/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_index_356166.js index 0d512981faad8..663718f36b3f5 100644 --- a/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_index_356166.js +++ b/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_index_356166.js @@ -1,6 +1,6 @@ (globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_index_356166.js", { -"[project]/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__, m: module, e: exports, t: require }) { !function() { +"[project]/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { __turbopack_esm__({}); ; diff --git a/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_style_7d7e1c.css.map b/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_style_7d7e1c.css.map index d3f2c54ec7f94..48fe5b49d62fa 100644 --- a/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_style_7d7e1c.css.map +++ b/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_style_7d7e1c.css.map @@ -2,6 +2,6 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/style.css"],"sourcesContent":["@import url(\"./a.css\") layer(layer) supports(not(display: inline-grid)) print;\n\n.style {\n color: yellow;\n}\n"],"names":[],"mappings":"AAEA"}}, + {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/style.css"],"sourcesContent":["@import url(\"./a.css\") layer(layer) supports(not(display: inline-grid)) print;\n\n.style {\n color: yellow;\n}\n"],"names":[],"mappings":"AAEA"}}, {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/output/crates_turbopack-tests_tests_snapshot_css_css-legacy-nesting_input_index_8e60f2.js b/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/output/crates_turbopack-tests_tests_snapshot_css_css-legacy-nesting_input_index_8e60f2.js index bb05fbb795fea..b93bcd884ca82 100644 --- a/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/output/crates_turbopack-tests_tests_snapshot_css_css-legacy-nesting_input_index_8e60f2.js +++ b/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/output/crates_turbopack-tests_tests_snapshot_css_css-legacy-nesting_input_index_8e60f2.js @@ -1,6 +1,6 @@ (globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_css_css-legacy-nesting_input_index_8e60f2.js", { -"[project]/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__, m: module, e: exports, t: require }) { !function() { +"[project]/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { __turbopack_esm__({}); ; diff --git a/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/output/crates_turbopack-tests_tests_snapshot_css_css-legacy-nesting_input_index_8e60f2.js.map b/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/output/crates_turbopack-tests_tests_snapshot_css_css-legacy-nesting_input_index_8e60f2.js.map index 9ea4762781719..fae772f721a68 100644 --- a/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/output/crates_turbopack-tests_tests_snapshot_css_css-legacy-nesting_input_index_8e60f2.js.map +++ b/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/output/crates_turbopack-tests_tests_snapshot_css_css-legacy-nesting_input_index_8e60f2.js.map @@ -2,6 +2,6 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/input/index.js"],"sourcesContent":["import \"./style.css\";\n\nconsole.log('css-legacy-nesting');\n"],"names":[],"mappings":";;AAEA,QAAQ,GAAG,CAAC"}}, + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/input/index.js"],"sourcesContent":["import \"./style.css\";\n\nconsole.log('css-legacy-nesting');\n"],"names":[],"mappings":";;AAEA,QAAQ,GAAG,CAAC"}}, {"offset": {"line": 7, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/output/crates_turbopack-tests_tests_snapshot_css_css-legacy-nesting_input_style_7d7e1c.css.map b/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/output/crates_turbopack-tests_tests_snapshot_css_css-legacy-nesting_input_style_7d7e1c.css.map index 8ae4d8c16d110..f539062ec0af1 100644 --- a/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/output/crates_turbopack-tests_tests_snapshot_css_css-legacy-nesting_input_style_7d7e1c.css.map +++ b/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/output/crates_turbopack-tests_tests_snapshot_css_css-legacy-nesting_input_style_7d7e1c.css.map @@ -2,6 +2,6 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/input/style.css"],"sourcesContent":[".prose :where(table):not(:where([class~=\"not-prose\"], [class~=\"not-prose\"] *)) {\n tr {\n td:first-child {\n text-wrap: nowrap;\n }\n }\n text-wrap: initial;\n}\n\n.prose :where(code):not(:where([class~=\"not-prose\"], [class~=\"not-prose\"] *)) {\n text-wrap: nowrap;\n}\n"],"names":[],"mappings":"AAAA;;;;AAEI;;;;AAOJ"}}, + {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/input/style.css"],"sourcesContent":[".prose :where(table):not(:where([class~=\"not-prose\"], [class~=\"not-prose\"] *)) {\n tr {\n td:first-child {\n text-wrap: nowrap;\n }\n }\n text-wrap: initial;\n}\n\n.prose :where(code):not(:where([class~=\"not-prose\"], [class~=\"not-prose\"] *)) {\n text-wrap: nowrap;\n}\n"],"names":[],"mappings":"AAAA;;;;AAEI;;;;AAOJ"}}, {"offset": {"line": 12, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/output/crates_turbopack-tests_tests_snapshot_css_css-legacy-nesting_input_style_c557a7.css.map b/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/output/crates_turbopack-tests_tests_snapshot_css_css-legacy-nesting_input_style_c557a7.css.map index 8ae4d8c16d110..f539062ec0af1 100644 --- a/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/output/crates_turbopack-tests_tests_snapshot_css_css-legacy-nesting_input_style_c557a7.css.map +++ b/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/output/crates_turbopack-tests_tests_snapshot_css_css-legacy-nesting_input_style_c557a7.css.map @@ -2,6 +2,6 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/input/style.css"],"sourcesContent":[".prose :where(table):not(:where([class~=\"not-prose\"], [class~=\"not-prose\"] *)) {\n tr {\n td:first-child {\n text-wrap: nowrap;\n }\n }\n text-wrap: initial;\n}\n\n.prose :where(code):not(:where([class~=\"not-prose\"], [class~=\"not-prose\"] *)) {\n text-wrap: nowrap;\n}\n"],"names":[],"mappings":"AAAA;;;;AAEI;;;;AAOJ"}}, + {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/input/style.css"],"sourcesContent":[".prose :where(table):not(:where([class~=\"not-prose\"], [class~=\"not-prose\"] *)) {\n tr {\n td:first-child {\n text-wrap: nowrap;\n }\n }\n text-wrap: initial;\n}\n\n.prose :where(code):not(:where([class~=\"not-prose\"], [class~=\"not-prose\"] *)) {\n text-wrap: nowrap;\n}\n"],"names":[],"mappings":"AAAA;;;;AAEI;;;;AAOJ"}}, {"offset": {"line": 12, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/css/css-modules/output/crates_turbopack-tests_tests_snapshot_css_css-modules_input_8abc52._.js b/crates/turbopack-tests/tests/snapshot/css/css-modules/output/crates_turbopack-tests_tests_snapshot_css_css-modules_input_8abc52._.js index d19cb4e50c55f..f35bc3201e0e7 100644 --- a/crates/turbopack-tests/tests/snapshot/css/css-modules/output/crates_turbopack-tests_tests_snapshot_css_css-modules_input_8abc52._.js +++ b/crates/turbopack-tests/tests/snapshot/css/css-modules/output/crates_turbopack-tests_tests_snapshot_css_css-modules_input_8abc52._.js @@ -12,7 +12,7 @@ __turbopack_export_value__({ }); })()), -"[project]/crates/turbopack-tests/tests/snapshot/css/css-modules/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/css/css-modules/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; __turbopack_esm__({}); diff --git a/crates/turbopack-tests/tests/snapshot/css/css-modules/output/crates_turbopack-tests_tests_snapshot_css_css-modules_input_8abc52._.js.map b/crates/turbopack-tests/tests/snapshot/css/css-modules/output/crates_turbopack-tests_tests_snapshot_css_css-modules_input_8abc52._.js.map index 9c1fa14451132..a2bb8a6258da6 100644 --- a/crates/turbopack-tests/tests/snapshot/css/css-modules/output/crates_turbopack-tests_tests_snapshot_css_css-modules_input_8abc52._.js.map +++ b/crates/turbopack-tests/tests/snapshot/css/css-modules/output/crates_turbopack-tests_tests_snapshot_css_css-modules_input_8abc52._.js.map @@ -2,8 +2,8 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/css/css-modules/input/style.module.css [test] (css module)"],"sourcesContent":["__turbopack_export_value__({\n \"actions\": \"style-module__mnEziG__actions\",\n \"avatar\": \"style-module__mnEziG__avatar\",\n \"checkbox\": \"style-module__mnEziG__checkbox\",\n \"content\": \"style-module__mnEziG__content\",\n \"menu\": \"style-module__mnEziG__menu\",\n \"module-style\": \"style-module__mnEziG__module-style\",\n});\n"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA"}}, + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/css-modules/input/style.module.css [test] (css module)"],"sourcesContent":["__turbopack_export_value__({\n \"actions\": \"style-module__mnEziG__actions\",\n \"avatar\": \"style-module__mnEziG__avatar\",\n \"checkbox\": \"style-module__mnEziG__checkbox\",\n \"content\": \"style-module__mnEziG__content\",\n \"menu\": \"style-module__mnEziG__menu\",\n \"module-style\": \"style-module__mnEziG__module-style\",\n});\n"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA"}}, {"offset": {"line": 12, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 17, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/css/css-modules/input/index.js"],"sourcesContent":["import style from \"./style.module.css\";\n\nconsole.log(style, import(\"./style.module.css\"));\n"],"names":[],"mappings":";;;;AAEA,QAAQ,GAAG,CAAC,kMAAA,CAAA,UAAK"}}, + {"offset": {"line": 17, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/css-modules/input/index.js"],"sourcesContent":["import style from \"./style.module.css\";\n\nconsole.log(style, import(\"./style.module.css\"));\n"],"names":[],"mappings":";;;;AAEA,QAAQ,GAAG,CAAC,kMAAA,CAAA,UAAK"}}, {"offset": {"line": 22, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/css/css-modules/output/crates_turbopack-tests_tests_snapshot_css_css-modules_input_style_module_71f14f.css.map b/crates/turbopack-tests/tests/snapshot/css/css-modules/output/crates_turbopack-tests_tests_snapshot_css_css-modules_input_style_module_71f14f.css.map index df6de27b1aed7..1d1ae26f1aadb 100644 --- a/crates/turbopack-tests/tests/snapshot/css/css-modules/output/crates_turbopack-tests_tests_snapshot_css_css-modules_input_style_module_71f14f.css.map +++ b/crates/turbopack-tests/tests/snapshot/css/css-modules/output/crates_turbopack-tests_tests_snapshot_css_css-modules_input_style_module_71f14f.css.map @@ -2,6 +2,6 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/css/css-modules/input/style.module.css"],"sourcesContent":[".module-style {\n grid-template-areas: 'checkbox avatar content actions menu';\n}\n\n"],"names":[],"mappings":"AAAA"}}, + {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/css-modules/input/style.module.css"],"sourcesContent":[".module-style {\n grid-template-areas: 'checkbox avatar content actions menu';\n}\n\n"],"names":[],"mappings":"AAAA"}}, {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/css/css-modules/output/crates_turbopack-tests_tests_snapshot_css_css-modules_input_style_module_7d7e1c.css.map b/crates/turbopack-tests/tests/snapshot/css/css-modules/output/crates_turbopack-tests_tests_snapshot_css_css-modules_input_style_module_7d7e1c.css.map index df6de27b1aed7..1d1ae26f1aadb 100644 --- a/crates/turbopack-tests/tests/snapshot/css/css-modules/output/crates_turbopack-tests_tests_snapshot_css_css-modules_input_style_module_7d7e1c.css.map +++ b/crates/turbopack-tests/tests/snapshot/css/css-modules/output/crates_turbopack-tests_tests_snapshot_css_css-modules_input_style_module_7d7e1c.css.map @@ -2,6 +2,6 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/css/css-modules/input/style.module.css"],"sourcesContent":[".module-style {\n grid-template-areas: 'checkbox avatar content actions menu';\n}\n\n"],"names":[],"mappings":"AAAA"}}, + {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/css-modules/input/style.module.css"],"sourcesContent":[".module-style {\n grid-template-areas: 'checkbox avatar content actions menu';\n}\n\n"],"names":[],"mappings":"AAAA"}}, {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/css/css/output/8697f_foo_style_7d7e1c.css.map b/crates/turbopack-tests/tests/snapshot/css/css/output/8697f_foo_style_7d7e1c.css.map index 80d727f1d739e..b077bf6e09cbf 100644 --- a/crates/turbopack-tests/tests/snapshot/css/css/output/8697f_foo_style_7d7e1c.css.map +++ b/crates/turbopack-tests/tests/snapshot/css/css/output/8697f_foo_style_7d7e1c.css.map @@ -2,6 +2,6 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/css/css/input/node_modules/foo/style.css"],"sourcesContent":[".foo-style { color: green; }\n"],"names":[],"mappings":"AAAA"}}, + {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/css/input/node_modules/foo/style.css"],"sourcesContent":[".foo-style { color: green; }\n"],"names":[],"mappings":"AAAA"}}, {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/css/css/output/8697f_foo_style_module_7d7e1c.css.map b/crates/turbopack-tests/tests/snapshot/css/css/output/8697f_foo_style_module_7d7e1c.css.map index 9fe586a6c4ceb..ef8b8cd2f4eaa 100644 --- a/crates/turbopack-tests/tests/snapshot/css/css/output/8697f_foo_style_module_7d7e1c.css.map +++ b/crates/turbopack-tests/tests/snapshot/css/css/output/8697f_foo_style_module_7d7e1c.css.map @@ -2,6 +2,6 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/css/css/input/node_modules/foo/style.module.css"],"sourcesContent":[".foo-module-style { color: blue; }\n"],"names":[],"mappings":"AAAA"}}, + {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/css/input/node_modules/foo/style.module.css"],"sourcesContent":[".foo-module-style { color: blue; }\n"],"names":[],"mappings":"AAAA"}}, {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_34944c._.js b/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_34944c._.js index 544235438cd0b..f5c0737341f90 100644 --- a/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_34944c._.js +++ b/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_34944c._.js @@ -10,7 +10,7 @@ __turbopack_export_value__({ }); })()), -"[project]/crates/turbopack-tests/tests/snapshot/css/css/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/css/css/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; __turbopack_esm__({}); diff --git a/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_34944c._.js.map b/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_34944c._.js.map index 96e471f959055..79093448e0f33 100644 --- a/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_34944c._.js.map +++ b/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_34944c._.js.map @@ -2,10 +2,10 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/css/css/input/style.module.css [test] (css module)"],"sourcesContent":["__turbopack_export_value__({\n \"another-composed-module-style\": \"style-module__YW1Vbq__another-composed-module-style\" + \" \" + __turbopack_import__(\"[project]/crates/turbopack-tests/tests/snapshot/css/css/input/node_modules/foo/style.module.css [test] (css module)\")[\"foo-module-style\"],\n \"composed-module-style\": \"style-module__YW1Vbq__composed-module-style\" + \" \" + __turbopack_import__(\"[project]/crates/turbopack-tests/tests/snapshot/css/css/input/node_modules/foo/style.module.css [test] (css module)\")[\"foo-module-style\"],\n \"inner\": \"style-module__YW1Vbq__inner\",\n \"module-style\": \"style-module__YW1Vbq__module-style\",\n});\n"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA"}}, + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/css/input/style.module.css [test] (css module)"],"sourcesContent":["__turbopack_export_value__({\n \"another-composed-module-style\": \"style-module__YW1Vbq__another-composed-module-style\" + \" \" + __turbopack_import__(\"[project]/crates/turbopack-tests/tests/snapshot/css/css/input/node_modules/foo/style.module.css [test] (css module)\")[\"foo-module-style\"],\n \"composed-module-style\": \"style-module__YW1Vbq__composed-module-style\" + \" \" + __turbopack_import__(\"[project]/crates/turbopack-tests/tests/snapshot/css/css/input/node_modules/foo/style.module.css [test] (css module)\")[\"foo-module-style\"],\n \"inner\": \"style-module__YW1Vbq__inner\",\n \"module-style\": \"style-module__YW1Vbq__module-style\",\n});\n"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA"}}, {"offset": {"line": 10, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 15, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/css/css/input/index.js"],"sourcesContent":["import \"foo/style.css\";\nimport \"foo\";\nimport \"./style.css\";\nimport fooStyle from \"foo/style.module.css\";\nimport style from \"./style.module.css\";\n\nconsole.log(style, fooStyle, import(\"foo\"));\n"],"names":[],"mappings":";;;;;;;;;AAMA,QAAQ,GAAG,CAAC,uLAAA,CAAA,UAAK,EAAE,8MAAA,CAAA,UAAQ"}}, + {"offset": {"line": 15, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/css/input/index.js"],"sourcesContent":["import \"foo/style.css\";\nimport \"foo\";\nimport \"./style.css\";\nimport fooStyle from \"foo/style.module.css\";\nimport style from \"./style.module.css\";\n\nconsole.log(style, fooStyle, import(\"foo\"));\n"],"names":[],"mappings":";;;;;;;;;AAMA,QAAQ,GAAG,CAAC,uLAAA,CAAA,UAAK,EAAE,8MAAA,CAAA,UAAQ"}}, {"offset": {"line": 25, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 29, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/css/css/input/node_modules/foo/style.module.css [test] (css module)"],"sourcesContent":["__turbopack_export_value__({\n \"foo-module-style\": \"style-module__6THCLW__foo-module-style\",\n});\n"],"names":[],"mappings":"AAAA;AACA;AACA"}}, + {"offset": {"line": 29, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/css/input/node_modules/foo/style.module.css [test] (css module)"],"sourcesContent":["__turbopack_export_value__({\n \"foo-module-style\": \"style-module__6THCLW__foo-module-style\",\n});\n"],"names":[],"mappings":"AAAA;AACA;AACA"}}, {"offset": {"line": 32, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_f3a64b._.css.map b/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_f3a64b._.css.map index fa57a69ca89dd..521c93bc84e7e 100644 --- a/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_f3a64b._.css.map +++ b/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_f3a64b._.css.map @@ -2,16 +2,16 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/css/css/input/imported.css"],"sourcesContent":[".imported {\n color: cyan;\n}\n"],"names":[],"mappings":"AAAA"}}, + {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/css/input/imported.css"],"sourcesContent":[".imported {\n color: cyan;\n}\n"],"names":[],"mappings":"AAAA"}}, {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 9, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/css/css/input/imported.css"],"sourcesContent":[".imported {\n color: cyan;\n}\n"],"names":[],"mappings":"AAAA"}}, + {"offset": {"line": 9, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/css/input/imported.css"],"sourcesContent":[".imported {\n color: cyan;\n}\n"],"names":[],"mappings":"AAAA"}}, {"offset": {"line": 12, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 17, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/css/css/input/style.css"],"sourcesContent":["@import url(\"./imported.css\");\n/* De-duplicate similar imports */\n@import url(\"../input/imported.css\");\n/* But not if they have different attributes */\n@import url(\"./imported.css\") layer(layer) print;\n.style {\n color: yellow;\n}\n"],"names":[],"mappings":"AAKA"}}, + {"offset": {"line": 17, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/css/input/style.css"],"sourcesContent":["@import url(\"./imported.css\");\n/* De-duplicate similar imports */\n@import url(\"../input/imported.css\");\n/* But not if they have different attributes */\n@import url(\"./imported.css\") layer(layer) print;\n.style {\n color: yellow;\n}\n"],"names":[],"mappings":"AAKA"}}, {"offset": {"line": 20, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 23, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/css/css/input/style.module.css"],"sourcesContent":[".module-style {\n color: magenta;\n > h1,\n + .inner {\n background: purple;\n }\n}\n\n.composed-module-style {\n composes: foo-module-style from \"foo/style.module.css\";\n color: green;\n}\n\n.another-composed-module-style {\n composes: foo-module-style from \"foo/style.module.css\";\n color: yellow;\n}"],"names":[],"mappings":"AAAA;;;;AAEE;;;;AAMF;;;;AAKA"}}, + {"offset": {"line": 23, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/css/input/style.module.css"],"sourcesContent":[".module-style {\n color: magenta;\n > h1,\n + .inner {\n background: purple;\n }\n}\n\n.composed-module-style {\n composes: foo-module-style from \"foo/style.module.css\";\n color: green;\n}\n\n.another-composed-module-style {\n composes: foo-module-style from \"foo/style.module.css\";\n color: yellow;\n}"],"names":[],"mappings":"AAAA;;;;AAEE;;;;AAMF;;;;AAKA"}}, {"offset": {"line": 38, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 41, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/css/css/input/node_modules/foo/style.css"],"sourcesContent":[".foo-style { color: green; }\n"],"names":[],"mappings":"AAAA"}}, + {"offset": {"line": 41, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/css/input/node_modules/foo/style.css"],"sourcesContent":[".foo-style { color: green; }\n"],"names":[],"mappings":"AAAA"}}, {"offset": {"line": 44, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 47, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/css/css/input/node_modules/foo/style.module.css"],"sourcesContent":[".foo-module-style { color: blue; }\n"],"names":[],"mappings":"AAAA"}}, + {"offset": {"line": 47, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/css/input/node_modules/foo/style.module.css"],"sourcesContent":[".foo-module-style { color: blue; }\n"],"names":[],"mappings":"AAAA"}}, {"offset": {"line": 50, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_imported_9f97d9.css.map b/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_imported_9f97d9.css.map index e21598d9b563f..b295305bc5aa4 100644 --- a/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_imported_9f97d9.css.map +++ b/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_imported_9f97d9.css.map @@ -2,6 +2,6 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 3, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/css/css/input/imported.css"],"sourcesContent":[".imported {\n color: cyan;\n}\n"],"names":[],"mappings":"AAAA"}}, + {"offset": {"line": 3, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/css/input/imported.css"],"sourcesContent":[".imported {\n color: cyan;\n}\n"],"names":[],"mappings":"AAAA"}}, {"offset": {"line": 6, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_imported_d96429.css.map b/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_imported_d96429.css.map index 76d24ba9c1c21..e2b22b44eb1de 100644 --- a/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_imported_d96429.css.map +++ b/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_imported_d96429.css.map @@ -2,6 +2,6 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/css/css/input/imported.css"],"sourcesContent":[".imported {\n color: cyan;\n}\n"],"names":[],"mappings":"AAAA"}}, + {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/css/input/imported.css"],"sourcesContent":[".imported {\n color: cyan;\n}\n"],"names":[],"mappings":"AAAA"}}, {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_style_7d7e1c.css.map b/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_style_7d7e1c.css.map index 5e0c71b9ad484..d0dfce55efcfc 100644 --- a/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_style_7d7e1c.css.map +++ b/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_style_7d7e1c.css.map @@ -2,6 +2,6 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/css/css/input/style.css"],"sourcesContent":["@import url(\"./imported.css\");\n/* De-duplicate similar imports */\n@import url(\"../input/imported.css\");\n/* But not if they have different attributes */\n@import url(\"./imported.css\") layer(layer) print;\n.style {\n color: yellow;\n}\n"],"names":[],"mappings":"AAKA"}}, + {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/css/input/style.css"],"sourcesContent":["@import url(\"./imported.css\");\n/* De-duplicate similar imports */\n@import url(\"../input/imported.css\");\n/* But not if they have different attributes */\n@import url(\"./imported.css\") layer(layer) print;\n.style {\n color: yellow;\n}\n"],"names":[],"mappings":"AAKA"}}, {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_style_module_7d7e1c.css.map b/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_style_module_7d7e1c.css.map index 367cd6acebc0d..1fd4f12a986c2 100644 --- a/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_style_module_7d7e1c.css.map +++ b/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_style_module_7d7e1c.css.map @@ -2,6 +2,6 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/css/css/input/style.module.css"],"sourcesContent":[".module-style {\n color: magenta;\n > h1,\n + .inner {\n background: purple;\n }\n}\n\n.composed-module-style {\n composes: foo-module-style from \"foo/style.module.css\";\n color: green;\n}\n\n.another-composed-module-style {\n composes: foo-module-style from \"foo/style.module.css\";\n color: yellow;\n}"],"names":[],"mappings":"AAAA;;;;AAEE;;;;AAMF;;;;AAKA"}}, + {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/css/input/style.module.css"],"sourcesContent":[".module-style {\n color: magenta;\n > h1,\n + .inner {\n background: purple;\n }\n}\n\n.composed-module-style {\n composes: foo-module-style from \"foo/style.module.css\";\n color: green;\n}\n\n.another-composed-module-style {\n composes: foo-module-style from \"foo/style.module.css\";\n color: yellow;\n}"],"names":[],"mappings":"AAAA;;;;AAEE;;;;AAMF;;;;AAKA"}}, {"offset": {"line": 16, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/output/79fb1_turbopack-tests_tests_snapshot_css_relative-uri-import_input_another_d96429.css.map b/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/output/79fb1_turbopack-tests_tests_snapshot_css_relative-uri-import_input_another_d96429.css.map index 4a1322121a485..9e6463624945f 100644 --- a/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/output/79fb1_turbopack-tests_tests_snapshot_css_relative-uri-import_input_another_d96429.css.map +++ b/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/output/79fb1_turbopack-tests_tests_snapshot_css_relative-uri-import_input_another_d96429.css.map @@ -2,6 +2,6 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/input/another.css"],"sourcesContent":[".bar {\n background-color: green;\n}\n"],"names":[],"mappings":"AAAA"}}, + {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/input/another.css"],"sourcesContent":[".bar {\n background-color: green;\n}\n"],"names":[],"mappings":"AAAA"}}, {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/output/crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_dc7e6c._.css.map b/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/output/crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_dc7e6c._.css.map index 1e821743a2cad..cb8a40708749e 100644 --- a/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/output/crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_dc7e6c._.css.map +++ b/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/output/crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_dc7e6c._.css.map @@ -2,10 +2,10 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/input/another.css"],"sourcesContent":[".bar {\n background-color: green;\n}\n"],"names":[],"mappings":"AAAA"}}, + {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/input/another.css"],"sourcesContent":[".bar {\n background-color: green;\n}\n"],"names":[],"mappings":"AAAA"}}, {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 7, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/input/other.css"],"sourcesContent":["@import \"another.css\";\n\n.foo {\n background-color: red;\n}\n"],"names":[],"mappings":"AAEA"}}, + {"offset": {"line": 7, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/input/other.css"],"sourcesContent":["@import \"another.css\";\n\n.foo {\n background-color: red;\n}\n"],"names":[],"mappings":"AAEA"}}, {"offset": {"line": 10, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 13, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/input/index.css"],"sourcesContent":["@import \"other.css\";\n\nbody {\n background-color: blue;\n}\n"],"names":[],"mappings":"AAEA"}}, + {"offset": {"line": 13, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/input/index.css"],"sourcesContent":["@import \"other.css\";\n\nbody {\n background-color: blue;\n}\n"],"names":[],"mappings":"AAEA"}}, {"offset": {"line": 16, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/output/crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_index_7d7e1c.css.map b/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/output/crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_index_7d7e1c.css.map index 428a95f28136a..e937ad402c60b 100644 --- a/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/output/crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_index_7d7e1c.css.map +++ b/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/output/crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_index_7d7e1c.css.map @@ -2,6 +2,6 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/input/index.css"],"sourcesContent":["@import \"other.css\";\n\nbody {\n background-color: blue;\n}\n"],"names":[],"mappings":"AAEA"}}, + {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/input/index.css"],"sourcesContent":["@import \"other.css\";\n\nbody {\n background-color: blue;\n}\n"],"names":[],"mappings":"AAEA"}}, {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/output/crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_index_c2ad30.js b/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/output/crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_index_c2ad30.js index e18d3fa0e0479..8157d0dabdba1 100644 --- a/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/output/crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_index_c2ad30.js +++ b/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/output/crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_index_c2ad30.js @@ -1,6 +1,6 @@ (globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_index_c2ad30.js", { -"[project]/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__, m: module, e: exports, t: require }) { !function() { +"[project]/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { __turbopack_esm__({}); ; diff --git a/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/output/crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_other_d96429.css.map b/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/output/crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_other_d96429.css.map index 184582839d8ff..fd3d15054a0ec 100644 --- a/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/output/crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_other_d96429.css.map +++ b/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/output/crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_other_d96429.css.map @@ -2,6 +2,6 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/input/other.css"],"sourcesContent":["@import \"another.css\";\n\n.foo {\n background-color: red;\n}\n"],"names":[],"mappings":"AAEA"}}, + {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/input/other.css"],"sourcesContent":["@import \"another.css\";\n\n.foo {\n background-color: red;\n}\n"],"names":[],"mappings":"AAEA"}}, {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/output/79fb1_turbopack-tests_tests_snapshot_css_url-in-supports-query_input_index_c70a2c.js b/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/output/79fb1_turbopack-tests_tests_snapshot_css_url-in-supports-query_input_index_c70a2c.js index f653cff03513a..b5829da128ecc 100644 --- a/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/output/79fb1_turbopack-tests_tests_snapshot_css_url-in-supports-query_input_index_c70a2c.js +++ b/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/output/79fb1_turbopack-tests_tests_snapshot_css_url-in-supports-query_input_index_c70a2c.js @@ -1,6 +1,6 @@ (globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/79fb1_turbopack-tests_tests_snapshot_css_url-in-supports-query_input_index_c70a2c.js", { -"[project]/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__, m: module, e: exports, t: require }) { !function() { +"[project]/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { __turbopack_esm__({}); ; diff --git a/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/output/79fb1_turbopack-tests_tests_snapshot_css_url-in-supports-query_input_style_4b6496.css.map b/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/output/79fb1_turbopack-tests_tests_snapshot_css_url-in-supports-query_input_style_4b6496.css.map index f2c5a4e52ba91..6caf936272238 100644 --- a/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/output/79fb1_turbopack-tests_tests_snapshot_css_url-in-supports-query_input_style_4b6496.css.map +++ b/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/output/79fb1_turbopack-tests_tests_snapshot_css_url-in-supports-query_input_style_4b6496.css.map @@ -2,6 +2,6 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/input/style.css"],"sourcesContent":["@supports ((-webkit-mask: url(\"\")) or (mask: url(\"\"))) {\n .supports-url-in-query {\n color: red;\n }\n}\n"],"names":[],"mappings":"AAAA,CAAC,QAAQ,CAAE,CAAC,CAAC,AAAD,YAAY,EAAE,GAAG,CAAC,EAAE,CAAA,CAAC,IAAM,CAAC,AAAD,IAAI,EAAE,GAAG,CAAC,EAAE,CAAA,CAAC,CAAC,CAAE,CAAC;EACtD,CAAC,qBAAqB,CAAC,CAAC;IACtB,KAAK,EAAE,GAAG;EACZ,CAAC;AACH,CAAC"}}, + {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/input/style.css"],"sourcesContent":["@supports ((-webkit-mask: url(\"\")) or (mask: url(\"\"))) {\n .supports-url-in-query {\n color: red;\n }\n}\n"],"names":[],"mappings":"AAAA,CAAC,QAAQ,CAAE,CAAC,CAAC,AAAD,YAAY,EAAE,GAAG,CAAC,EAAE,CAAA,CAAC,IAAM,CAAC,AAAD,IAAI,EAAE,GAAG,CAAC,EAAE,CAAA,CAAC,CAAC,CAAE,CAAC;EACtD,CAAC,qBAAqB,CAAC,CAAC;IACtB,KAAK,EAAE,GAAG;EACZ,CAAC;AACH,CAAC"}}, {"offset": {"line": 5, "column": 1}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/output/79fb1_turbopack-tests_tests_snapshot_css_url-in-supports-query_input_style_a5a67a.css.map b/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/output/79fb1_turbopack-tests_tests_snapshot_css_url-in-supports-query_input_style_a5a67a.css.map index f2c5a4e52ba91..6caf936272238 100644 --- a/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/output/79fb1_turbopack-tests_tests_snapshot_css_url-in-supports-query_input_style_a5a67a.css.map +++ b/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/output/79fb1_turbopack-tests_tests_snapshot_css_url-in-supports-query_input_style_a5a67a.css.map @@ -2,6 +2,6 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/input/style.css"],"sourcesContent":["@supports ((-webkit-mask: url(\"\")) or (mask: url(\"\"))) {\n .supports-url-in-query {\n color: red;\n }\n}\n"],"names":[],"mappings":"AAAA,CAAC,QAAQ,CAAE,CAAC,CAAC,AAAD,YAAY,EAAE,GAAG,CAAC,EAAE,CAAA,CAAC,IAAM,CAAC,AAAD,IAAI,EAAE,GAAG,CAAC,EAAE,CAAA,CAAC,CAAC,CAAE,CAAC;EACtD,CAAC,qBAAqB,CAAC,CAAC;IACtB,KAAK,EAAE,GAAG;EACZ,CAAC;AACH,CAAC"}}, + {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/input/style.css"],"sourcesContent":["@supports ((-webkit-mask: url(\"\")) or (mask: url(\"\"))) {\n .supports-url-in-query {\n color: red;\n }\n}\n"],"names":[],"mappings":"AAAA,CAAC,QAAQ,CAAE,CAAC,CAAC,AAAD,YAAY,EAAE,GAAG,CAAC,EAAE,CAAA,CAAC,IAAM,CAAC,AAAD,IAAI,EAAE,GAAG,CAAC,EAAE,CAAA,CAAC,CAAC,CAAE,CAAC;EACtD,CAAC,qBAAqB,CAAC,CAAC;IACtB,KAAK,EAAE,GAAG;EACZ,CAAC;AACH,CAAC"}}, {"offset": {"line": 5, "column": 1}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/cssmodules/composes/output/79fb1_turbopack-tests_tests_snapshot_cssmodules_composes_input_index_module_7d7e1c.css.map b/crates/turbopack-tests/tests/snapshot/cssmodules/composes/output/79fb1_turbopack-tests_tests_snapshot_cssmodules_composes_input_index_module_7d7e1c.css.map index 9b5c5498e6a08..e8880255cede2 100644 --- a/crates/turbopack-tests/tests/snapshot/cssmodules/composes/output/79fb1_turbopack-tests_tests_snapshot_cssmodules_composes_input_index_module_7d7e1c.css.map +++ b/crates/turbopack-tests/tests/snapshot/cssmodules/composes/output/79fb1_turbopack-tests_tests_snapshot_cssmodules_composes_input_index_module_7d7e1c.css.map @@ -2,6 +2,6 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/cssmodules/composes/input/index.module.css"],"sourcesContent":[".className {\n background: red;\n color: yellow;\n}\n\n.subClass {\n composes: className;\n background: blue;\n}\n"],"names":[],"mappings":"AAAA;;;;;AAKA"}}, + {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/cssmodules/composes/input/index.module.css"],"sourcesContent":[".className {\n background: red;\n color: yellow;\n}\n\n.subClass {\n composes: className;\n background: blue;\n}\n"],"names":[],"mappings":"AAAA;;;;;AAKA"}}, {"offset": {"line": 9, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/cssmodules/composes/output/79fb1_turbopack-tests_tests_snapshot_cssmodules_composes_input_index_module_cb674a.css.map b/crates/turbopack-tests/tests/snapshot/cssmodules/composes/output/79fb1_turbopack-tests_tests_snapshot_cssmodules_composes_input_index_module_cb674a.css.map index 9b5c5498e6a08..e8880255cede2 100644 --- a/crates/turbopack-tests/tests/snapshot/cssmodules/composes/output/79fb1_turbopack-tests_tests_snapshot_cssmodules_composes_input_index_module_cb674a.css.map +++ b/crates/turbopack-tests/tests/snapshot/cssmodules/composes/output/79fb1_turbopack-tests_tests_snapshot_cssmodules_composes_input_index_module_cb674a.css.map @@ -2,6 +2,6 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/cssmodules/composes/input/index.module.css"],"sourcesContent":[".className {\n background: red;\n color: yellow;\n}\n\n.subClass {\n composes: className;\n background: blue;\n}\n"],"names":[],"mappings":"AAAA;;;;;AAKA"}}, + {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/cssmodules/composes/input/index.module.css"],"sourcesContent":[".className {\n background: red;\n color: yellow;\n}\n\n.subClass {\n composes: className;\n background: blue;\n}\n"],"names":[],"mappings":"AAAA;;;;;AAKA"}}, {"offset": {"line": 9, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/cssmodules/composes/output/crates_turbopack-tests_tests_snapshot_cssmodules_composes_input_2ba052._.js b/crates/turbopack-tests/tests/snapshot/cssmodules/composes/output/crates_turbopack-tests_tests_snapshot_cssmodules_composes_input_2ba052._.js index ee24592b320a0..b6bf94049acaa 100644 --- a/crates/turbopack-tests/tests/snapshot/cssmodules/composes/output/crates_turbopack-tests_tests_snapshot_cssmodules_composes_input_2ba052._.js +++ b/crates/turbopack-tests/tests/snapshot/cssmodules/composes/output/crates_turbopack-tests_tests_snapshot_cssmodules_composes_input_2ba052._.js @@ -8,7 +8,7 @@ __turbopack_export_value__({ }); })()), -"[project]/crates/turbopack-tests/tests/snapshot/cssmodules/composes/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/cssmodules/composes/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; __turbopack_esm__({}); diff --git a/crates/turbopack-tests/tests/snapshot/cssmodules/composes/output/crates_turbopack-tests_tests_snapshot_cssmodules_composes_input_2ba052._.js.map b/crates/turbopack-tests/tests/snapshot/cssmodules/composes/output/crates_turbopack-tests_tests_snapshot_cssmodules_composes_input_2ba052._.js.map index df91d6e6de784..50ddd5eb83ec0 100644 --- a/crates/turbopack-tests/tests/snapshot/cssmodules/composes/output/crates_turbopack-tests_tests_snapshot_cssmodules_composes_input_2ba052._.js.map +++ b/crates/turbopack-tests/tests/snapshot/cssmodules/composes/output/crates_turbopack-tests_tests_snapshot_cssmodules_composes_input_2ba052._.js.map @@ -2,7 +2,7 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/cssmodules/composes/input/index.module.css [test] (css module)"],"sourcesContent":["__turbopack_export_value__({\n \"className\": \"index-module__Tw9iRq__className\",\n \"subClass\": \"index-module__Tw9iRq__subClass\" + \" \" + \"index-module__Tw9iRq__className\",\n});\n"],"names":[],"mappings":"AAAA;AACA;AACA;AACA"}}, + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/cssmodules/composes/input/index.module.css [test] (css module)"],"sourcesContent":["__turbopack_export_value__({\n \"className\": \"index-module__Tw9iRq__className\",\n \"subClass\": \"index-module__Tw9iRq__subClass\" + \" \" + \"index-module__Tw9iRq__className\",\n});\n"],"names":[],"mappings":"AAAA;AACA;AACA;AACA"}}, {"offset": {"line": 8, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, {"offset": {"line": 13, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, {"offset": {"line": 17, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] diff --git a/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/output/79fb1_turbopack-tests_tests_snapshot_cssmodules_relative-uri-import_input_6d6278._.css.map b/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/output/79fb1_turbopack-tests_tests_snapshot_cssmodules_relative-uri-import_input_6d6278._.css.map index afb870fe82ee5..ea017a744395b 100644 --- a/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/output/79fb1_turbopack-tests_tests_snapshot_cssmodules_relative-uri-import_input_6d6278._.css.map +++ b/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/output/79fb1_turbopack-tests_tests_snapshot_cssmodules_relative-uri-import_input_6d6278._.css.map @@ -2,8 +2,8 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/input/other.module.css"],"sourcesContent":[".foo {\n background-color: red;\n}\n"],"names":[],"mappings":"AAAA"}}, + {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/input/other.module.css"],"sourcesContent":[".foo {\n background-color: red;\n}\n"],"names":[],"mappings":"AAAA"}}, {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 7, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/input/index.module.css"],"sourcesContent":[".bar {\n composes: foo from 'other.module.css';\n}\n"],"names":[],"mappings":"AAAA"}}, + {"offset": {"line": 7, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/input/index.module.css"],"sourcesContent":[".bar {\n composes: foo from 'other.module.css';\n}\n"],"names":[],"mappings":"AAAA"}}, {"offset": {"line": 9, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/output/79fb1_turbopack-tests_tests_snapshot_cssmodules_relative-uri-import_input_f065a6._.js b/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/output/79fb1_turbopack-tests_tests_snapshot_cssmodules_relative-uri-import_input_f065a6._.js index f8bb19202920d..c111dc96f6d1a 100644 --- a/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/output/79fb1_turbopack-tests_tests_snapshot_cssmodules_relative-uri-import_input_f065a6._.js +++ b/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/output/79fb1_turbopack-tests_tests_snapshot_cssmodules_relative-uri-import_input_f065a6._.js @@ -14,7 +14,7 @@ __turbopack_export_value__({ }); })()), -"[project]/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; __turbopack_esm__({}); diff --git a/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/output/79fb1_turbopack-tests_tests_snapshot_cssmodules_relative-uri-import_input_f065a6._.js.map b/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/output/79fb1_turbopack-tests_tests_snapshot_cssmodules_relative-uri-import_input_f065a6._.js.map index 9ad964fdda815..51a37e55719d2 100644 --- a/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/output/79fb1_turbopack-tests_tests_snapshot_cssmodules_relative-uri-import_input_f065a6._.js.map +++ b/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/output/79fb1_turbopack-tests_tests_snapshot_cssmodules_relative-uri-import_input_f065a6._.js.map @@ -2,9 +2,9 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/input/other.module.css [test] (css module)"],"sourcesContent":["__turbopack_export_value__({\n \"foo\": \"other-module__O4Xnbq__foo\",\n});\n"],"names":[],"mappings":"AAAA;AACA;AACA"}}, + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/input/other.module.css [test] (css module)"],"sourcesContent":["__turbopack_export_value__({\n \"foo\": \"other-module__O4Xnbq__foo\",\n});\n"],"names":[],"mappings":"AAAA;AACA;AACA"}}, {"offset": {"line": 7, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 11, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/input/index.module.css [test] (css module)"],"sourcesContent":["__turbopack_export_value__({\n \"bar\": \"index-module__kgTkkG__bar\" + \" \" + __turbopack_import__(\"[project]/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/input/other.module.css [test] (css module)\")[\"foo\"],\n});\n"],"names":[],"mappings":"AAAA;AACA;AACA"}}, + {"offset": {"line": 11, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/input/index.module.css [test] (css module)"],"sourcesContent":["__turbopack_export_value__({\n \"bar\": \"index-module__kgTkkG__bar\" + \" \" + __turbopack_import__(\"[project]/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/input/other.module.css [test] (css module)\")[\"foo\"],\n});\n"],"names":[],"mappings":"AAAA;AACA;AACA"}}, {"offset": {"line": 14, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, {"offset": {"line": 19, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, {"offset": {"line": 23, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] diff --git a/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/output/a587c_tests_snapshot_cssmodules_relative-uri-import_input_index_module_7d7e1c.css.map b/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/output/a587c_tests_snapshot_cssmodules_relative-uri-import_input_index_module_7d7e1c.css.map index af871bc7b5371..4023ac1465cb0 100644 --- a/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/output/a587c_tests_snapshot_cssmodules_relative-uri-import_input_index_module_7d7e1c.css.map +++ b/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/output/a587c_tests_snapshot_cssmodules_relative-uri-import_input_index_module_7d7e1c.css.map @@ -2,6 +2,6 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/input/index.module.css"],"sourcesContent":[".bar {\n composes: foo from 'other.module.css';\n}\n"],"names":[],"mappings":"AAAA"}}, + {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/input/index.module.css"],"sourcesContent":[".bar {\n composes: foo from 'other.module.css';\n}\n"],"names":[],"mappings":"AAAA"}}, {"offset": {"line": 3, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/output/a587c_tests_snapshot_cssmodules_relative-uri-import_input_other_module_7d7e1c.css.map b/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/output/a587c_tests_snapshot_cssmodules_relative-uri-import_input_other_module_7d7e1c.css.map index ad914818ef817..b436945bf266f 100644 --- a/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/output/a587c_tests_snapshot_cssmodules_relative-uri-import_input_other_module_7d7e1c.css.map +++ b/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/output/a587c_tests_snapshot_cssmodules_relative-uri-import_input_other_module_7d7e1c.css.map @@ -2,6 +2,6 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/input/other.module.css"],"sourcesContent":[".foo {\n background-color: red;\n}\n"],"names":[],"mappings":"AAAA"}}, + {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/input/other.module.css"],"sourcesContent":[".foo {\n background-color: red;\n}\n"],"names":[],"mappings":"AAAA"}}, {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/output/79fb1_turbopack-tests_tests_snapshot_dynamic-request_very-dynamic_input_index_0d92c3.js b/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/output/79fb1_turbopack-tests_tests_snapshot_dynamic-request_very-dynamic_input_index_0d92c3.js index 0d76aca2628b2..fd67efa012ecd 100644 --- a/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/output/79fb1_turbopack-tests_tests_snapshot_dynamic-request_very-dynamic_input_index_0d92c3.js +++ b/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/output/79fb1_turbopack-tests_tests_snapshot_dynamic-request_very-dynamic_input_index_0d92c3.js @@ -1,6 +1,6 @@ (globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/79fb1_turbopack-tests_tests_snapshot_dynamic-request_very-dynamic_input_index_0d92c3.js", { -"[project]/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, x: __turbopack_external_require__, y: __turbopack_external_import__, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, x: __turbopack_external_require__, y: __turbopack_external_import__ }) => (() => { "use strict"; __turbopack_esm__({}); diff --git a/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/output/79fb1_turbopack-tests_tests_snapshot_dynamic-request_very-dynamic_input_index_0d92c3.js.map b/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/output/79fb1_turbopack-tests_tests_snapshot_dynamic-request_very-dynamic_input_index_0d92c3.js.map index 36cc452117582..833d6af6987a4 100644 --- a/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/output/79fb1_turbopack-tests_tests_snapshot_dynamic-request_very-dynamic_input_index_0d92c3.js.map +++ b/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/output/79fb1_turbopack-tests_tests_snapshot_dynamic-request_very-dynamic_input_index_0d92c3.js.map @@ -2,6 +2,6 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/input/index.js"],"sourcesContent":["import child_process from \"node:child_process\";\nimport fs, { readFileSync } from \"node:fs\";\n\nconst unknown = Math.random();\n\nchild_process.spawnSync(unknown);\nchild_process.spawnSync(\"node\", unknown);\nchild_process.spawnSync(\"node\", [unknown, unknown]);\n\nrequire(unknown);\n\nimport(unknown);\n\nfs.readFileSync(unknown);\nreadFileSync(unknown);\n\nnew URL(unknown, import.meta.url);\n"],"names":[],"mappings":";;;;;;;;;;;AAGA,MAAM,UAAU,KAAK,MAAM;AAE3B,mDAAA,CAAA,UAAa,CAAC,SAAS,CAAC;AACxB,mDAAA,CAAA,UAAa,CAAC,SAAS,CAAC,QAAQ;AAChC,mDAAA,CAAA,UAAa,CAAC,SAAS,CAAC,QAAQ;IAAC;IAAS;CAAQ;;;;;;;;;;;AAMlD,wCAAA,CAAA,UAAE,CAAC,YAAY,CAAC;AAChB,CAAA,GAAA,wCAAA,CAAA,eAAY,AAAD,EAAE;AAEb,IAAI,IAAI,SAAS,8BAAY,GAAG"}}, + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/input/index.js"],"sourcesContent":["import child_process from \"node:child_process\";\nimport fs, { readFileSync } from \"node:fs\";\n\nconst unknown = Math.random();\n\nchild_process.spawnSync(unknown);\nchild_process.spawnSync(\"node\", unknown);\nchild_process.spawnSync(\"node\", [unknown, unknown]);\n\nrequire(unknown);\n\nimport(unknown);\n\nfs.readFileSync(unknown);\nreadFileSync(unknown);\n\nnew URL(unknown, import.meta.url);\n"],"names":[],"mappings":";;;;;;;;;;;AAGA,MAAM,UAAU,KAAK,MAAM;AAE3B,mDAAA,CAAA,UAAa,CAAC,SAAS,CAAC;AACxB,mDAAA,CAAA,UAAa,CAAC,SAAS,CAAC,QAAQ;AAChC,mDAAA,CAAA,UAAa,CAAC,SAAS,CAAC,QAAQ;IAAC;IAAS;CAAQ;;;;;;;;;;;AAMlD,wCAAA,CAAA,UAAE,CAAC,YAAY,CAAC;AAChB,CAAA,GAAA,wCAAA,CAAA,eAAY,AAAD,EAAE;AAEb,IAAI,IAAI,SAAS,8BAAY,GAAG"}}, {"offset": {"line": 36, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/emotion/emotion/output/crates_turbopack-tests_tests_snapshot_b36339._.js b/crates/turbopack-tests/tests/snapshot/emotion/emotion/output/crates_turbopack-tests_tests_snapshot_b36339._.js index 1bb656791d4e7..7e35bb31cc053 100644 --- a/crates/turbopack-tests/tests/snapshot/emotion/emotion/output/crates_turbopack-tests_tests_snapshot_b36339._.js +++ b/crates/turbopack-tests/tests/snapshot/emotion/emotion/output/crates_turbopack-tests_tests_snapshot_b36339._.js @@ -1,6 +1,6 @@ (globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_b36339._.js", { -"[project]/crates/turbopack-tests/tests/snapshot/emotion/emotion/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/emotion/emotion/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; /** @jsxImportSource @emotion/react */ __turbopack_esm__({}); @@ -29,19 +29,19 @@ function ClassNameButton({ children }) { console.log(StyledButton, ClassNameButton); })()), -"[project]/crates/turbopack-tests/tests/snapshot/node_modules/@emotion/react/jsx-dev-runtime.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__, m: module, e: exports, t: require }) { !function() { +"[project]/crates/turbopack-tests/tests/snapshot/node_modules/@emotion/react/jsx-dev-runtime.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { "purposefully empty stub"; "@emtion/react/jsx-dev-runtime.js"; }.call(this) }), -"[project]/crates/turbopack-tests/tests/snapshot/node_modules/@emotion/react/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__, m: module, e: exports, t: require }) { !function() { +"[project]/crates/turbopack-tests/tests/snapshot/node_modules/@emotion/react/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { "purposefully empty stub"; "@emtion/react/index.js"; }.call(this) }), -"[project]/crates/turbopack-tests/tests/snapshot/node_modules/@emotion/styled/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__, m: module, e: exports, t: require }) { !function() { +"[project]/crates/turbopack-tests/tests/snapshot/node_modules/@emotion/styled/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { "purposefully empty stub"; "@emtion/styled/index.js"; diff --git a/crates/turbopack-tests/tests/snapshot/emotion/emotion/output/crates_turbopack-tests_tests_snapshot_b36339._.js.map b/crates/turbopack-tests/tests/snapshot/emotion/emotion/output/crates_turbopack-tests_tests_snapshot_b36339._.js.map index c2b0c7bacdf50..5646d6f04b95b 100644 --- a/crates/turbopack-tests/tests/snapshot/emotion/emotion/output/crates_turbopack-tests_tests_snapshot_b36339._.js.map +++ b/crates/turbopack-tests/tests/snapshot/emotion/emotion/output/crates_turbopack-tests_tests_snapshot_b36339._.js.map @@ -2,12 +2,12 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/emotion/emotion/input/index.js"],"sourcesContent":["/** @jsxImportSource @emotion/react */\n\nimport { jsx } from \"@emotion/react\";\nimport styled from \"@emotion/styled\";\n\nconst StyledButton = styled.button`\n background: blue;\n`;\n\nfunction ClassNameButton({ children }) {\n return (\n \n {children}\n \n );\n}\n\nconsole.log(StyledButton, ClassNameButton);\n"],"names":[],"mappings":"AAAA,oCAAoC;;;;;;;;AAKpC,MAAM,6BAAe,CAAA,GAAA,2LAAA,CAAA,UAAM,AAAD;;;AAI1B,SAAS,gBAAgB,EAAE,QAAQ,EAAE;IACnC,qBACE,0NAAC;QACC,WAAW,GAAG,CAAC;;MAEf,CAAC;kBAEA;;;;;;AAGP;AAEA,QAAQ,GAAG,CAAC,cAAc"}}, + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/emotion/emotion/input/index.js"],"sourcesContent":["/** @jsxImportSource @emotion/react */\n\nimport { jsx } from \"@emotion/react\";\nimport styled from \"@emotion/styled\";\n\nconst StyledButton = styled.button`\n background: blue;\n`;\n\nfunction ClassNameButton({ children }) {\n return (\n \n {children}\n \n );\n}\n\nconsole.log(StyledButton, ClassNameButton);\n"],"names":[],"mappings":"AAAA,oCAAoC;;;;;;;;AAKpC,MAAM,6BAAe,CAAA,GAAA,2LAAA,CAAA,UAAM,AAAD;;;AAI1B,SAAS,gBAAgB,EAAE,QAAQ,EAAE;IACnC,qBACE,0NAAC;QACC,WAAW,GAAG,CAAC;;MAEf,CAAC;kBAEA;;;;;;AAGP;AAEA,QAAQ,GAAG,CAAC,cAAc"}}, {"offset": {"line": 29, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 33, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/node_modules/@emotion/react/jsx-dev-runtime.js"],"sourcesContent":["\"purposefully empty stub\";\n\"@emtion/react/jsx-dev-runtime.js\";\n"],"names":[],"mappings":"AAAA;AACA"}}, + {"offset": {"line": 33, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/node_modules/@emotion/react/jsx-dev-runtime.js"],"sourcesContent":["\"purposefully empty stub\";\n\"@emtion/react/jsx-dev-runtime.js\";\n"],"names":[],"mappings":"AAAA;AACA"}}, {"offset": {"line": 35, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 39, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/node_modules/@emotion/react/index.js"],"sourcesContent":["\"purposefully empty stub\";\n\"@emtion/react/index.js\";\n"],"names":[],"mappings":"AAAA;AACA"}}, + {"offset": {"line": 39, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/node_modules/@emotion/react/index.js"],"sourcesContent":["\"purposefully empty stub\";\n\"@emtion/react/index.js\";\n"],"names":[],"mappings":"AAAA;AACA"}}, {"offset": {"line": 41, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 45, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/node_modules/@emotion/styled/index.js"],"sourcesContent":["\"purposefully empty stub\";\n\"@emtion/styled/index.js\";\n"],"names":[],"mappings":"AAAA;AACA"}}, + {"offset": {"line": 45, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/node_modules/@emotion/styled/index.js"],"sourcesContent":["\"purposefully empty stub\";\n\"@emtion/styled/index.js\";\n"],"names":[],"mappings":"AAAA;AACA"}}, {"offset": {"line": 47, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/env/env/output/crates_turbopack-tests_tests_snapshot_env_env_input_673035._.js b/crates/turbopack-tests/tests/snapshot/env/env/output/crates_turbopack-tests_tests_snapshot_env_env_input_673035._.js index 0ed19d47a8787..cc481128b117c 100644 --- a/crates/turbopack-tests/tests/snapshot/env/env/output/crates_turbopack-tests_tests_snapshot_env_env_input_673035._.js +++ b/crates/turbopack-tests/tests/snapshot/env/env/output/crates_turbopack-tests_tests_snapshot_env_env_input_673035._.js @@ -1,6 +1,6 @@ (globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_env_env_input_673035._.js", { -"[project]/crates/turbopack-tests/tests/snapshot/env/env/input/.env/.env.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__, m: module, e: exports, t: require }) { !function() { +"[project]/crates/turbopack-tests/tests/snapshot/env/env/input/.env/.env.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { const env = process.env = { ...process.env @@ -11,7 +11,7 @@ env["FOO"] = foo; env["FOOBAR"] = foobar; }.call(this) }), -"[project]/crates/turbopack-tests/tests/snapshot/env/env/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__, m: module, e: exports, t: require }) { !function() { +"[project]/crates/turbopack-tests/tests/snapshot/env/env/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { console.log(process.env.FOOBAR); console.log(process.env.BARFOO); diff --git a/crates/turbopack-tests/tests/snapshot/env/env/output/crates_turbopack-tests_tests_snapshot_env_env_input_673035._.js.map b/crates/turbopack-tests/tests/snapshot/env/env/output/crates_turbopack-tests_tests_snapshot_env_env_input_673035._.js.map index 55edaf358b181..910ba0f6169f9 100644 --- a/crates/turbopack-tests/tests/snapshot/env/env/output/crates_turbopack-tests_tests_snapshot_env_env_input_673035._.js.map +++ b/crates/turbopack-tests/tests/snapshot/env/env/output/crates_turbopack-tests_tests_snapshot_env_env_input_673035._.js.map @@ -2,8 +2,8 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/env/env/input/.env/.env.js"],"sourcesContent":["const env = process.env = {...process.env};\n\nenv[\"ALLFOOBAR\"] = foobarfoobar;\nenv[\"BARFOO\"] = barfoo;\nenv[\"FOO\"] = foo;\nenv[\"FOOBAR\"] = foobar;\n"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG,GAAG;IAAC,GAAG,QAAQ,GAAG;AAAA;AAEzC,GAAG,CAAC,YAAY,GAAG;AACnB,GAAG,CAAC,SAAS,GAAG;AAChB,GAAG,CAAC,MAAM,GAAG;AACb,GAAG,CAAC,SAAS,GAAG"}}, + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/env/env/input/.env/.env.js"],"sourcesContent":["const env = process.env = {...process.env};\n\nenv[\"ALLFOOBAR\"] = foobarfoobar;\nenv[\"BARFOO\"] = barfoo;\nenv[\"FOO\"] = foo;\nenv[\"FOOBAR\"] = foobar;\n"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG,GAAG;IAAC,GAAG,QAAQ,GAAG;AAAA;AAEzC,GAAG,CAAC,YAAY,GAAG;AACnB,GAAG,CAAC,SAAS,GAAG;AAChB,GAAG,CAAC,MAAM,GAAG;AACb,GAAG,CAAC,SAAS,GAAG"}}, {"offset": {"line": 11, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 15, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/env/env/input/index.js"],"sourcesContent":["console.log(process.env.FOOBAR);\nconsole.log(process.env.BARFOO);\nconsole.log(process.env.ALLFOOBAR);\n"],"names":[],"mappings":"AAAA,QAAQ,GAAG,CAAC,QAAQ,GAAG,CAAC,MAAM;AAC9B,QAAQ,GAAG,CAAC,QAAQ,GAAG,CAAC,MAAM;AAC9B,QAAQ,GAAG,CAAC,QAAQ,GAAG,CAAC,SAAS"}}, + {"offset": {"line": 15, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/env/env/input/index.js"],"sourcesContent":["console.log(process.env.FOOBAR);\nconsole.log(process.env.BARFOO);\nconsole.log(process.env.ALLFOOBAR);\n"],"names":[],"mappings":"AAAA,QAAQ,GAAG,CAAC,QAAQ,GAAG,CAAC,MAAM;AAC9B,QAAQ,GAAG,CAAC,QAAQ,GAAG,CAAC,MAAM;AAC9B,QAAQ,GAAG,CAAC,QAAQ,GAAG,CAAC,SAAS"}}, {"offset": {"line": 18, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/evaluated_entrry/runtime_entry/output/a587c_tests_snapshot_evaluated_entrry_runtime_entry_input_index_97d560.js b/crates/turbopack-tests/tests/snapshot/evaluated_entrry/runtime_entry/output/a587c_tests_snapshot_evaluated_entrry_runtime_entry_input_index_97d560.js index d1eecd8422d71..3ee4945ac8c12 100644 --- a/crates/turbopack-tests/tests/snapshot/evaluated_entrry/runtime_entry/output/a587c_tests_snapshot_evaluated_entrry_runtime_entry_input_index_97d560.js +++ b/crates/turbopack-tests/tests/snapshot/evaluated_entrry/runtime_entry/output/a587c_tests_snapshot_evaluated_entrry_runtime_entry_input_index_97d560.js @@ -1,6 +1,6 @@ (globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/a587c_tests_snapshot_evaluated_entrry_runtime_entry_input_index_97d560.js", { -"[project]/crates/turbopack-tests/tests/snapshot/evaluated_entrry/runtime_entry/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__, m: module, e: exports, t: require }) { !function() { +"[project]/crates/turbopack-tests/tests/snapshot/evaluated_entrry/runtime_entry/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { console.log("hello world"); diff --git a/crates/turbopack-tests/tests/snapshot/evaluated_entrry/runtime_entry/output/a587c_tests_snapshot_evaluated_entrry_runtime_entry_input_index_97d560.js.map b/crates/turbopack-tests/tests/snapshot/evaluated_entrry/runtime_entry/output/a587c_tests_snapshot_evaluated_entrry_runtime_entry_input_index_97d560.js.map index cd3d14b9b49e0..2e7a45d8f0ba9 100644 --- a/crates/turbopack-tests/tests/snapshot/evaluated_entrry/runtime_entry/output/a587c_tests_snapshot_evaluated_entrry_runtime_entry_input_index_97d560.js.map +++ b/crates/turbopack-tests/tests/snapshot/evaluated_entrry/runtime_entry/output/a587c_tests_snapshot_evaluated_entrry_runtime_entry_input_index_97d560.js.map @@ -2,6 +2,6 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/evaluated_entrry/runtime_entry/input/index.js"],"sourcesContent":["console.log(\"hello world\");\n"],"names":[],"mappings":"AAAA,QAAQ,GAAG,CAAC"}}, + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/evaluated_entrry/runtime_entry/input/index.js"],"sourcesContent":["console.log(\"hello world\");\n"],"names":[],"mappings":"AAAA,QAAQ,GAAG,CAAC"}}, {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/example/example/output/crates_turbopack-tests_tests_snapshot_example_example_input_index_838420.js b/crates/turbopack-tests/tests/snapshot/example/example/output/crates_turbopack-tests_tests_snapshot_example_example_input_index_838420.js index 51fb1cc30cf16..cd3d30bb2a80d 100644 --- a/crates/turbopack-tests/tests/snapshot/example/example/output/crates_turbopack-tests_tests_snapshot_example_example_input_index_838420.js +++ b/crates/turbopack-tests/tests/snapshot/example/example/output/crates_turbopack-tests_tests_snapshot_example_example_input_index_838420.js @@ -1,6 +1,6 @@ (globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_example_example_input_index_838420.js", { -"[project]/crates/turbopack-tests/tests/snapshot/example/example/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__, m: module, e: exports, t: require }) { !function() { +"[project]/crates/turbopack-tests/tests/snapshot/example/example/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { console.log("hello world"); diff --git a/crates/turbopack-tests/tests/snapshot/example/example/output/crates_turbopack-tests_tests_snapshot_example_example_input_index_838420.js.map b/crates/turbopack-tests/tests/snapshot/example/example/output/crates_turbopack-tests_tests_snapshot_example_example_input_index_838420.js.map index 9da0150ce9ba8..feb2b5c3ed7e1 100644 --- a/crates/turbopack-tests/tests/snapshot/example/example/output/crates_turbopack-tests_tests_snapshot_example_example_input_index_838420.js.map +++ b/crates/turbopack-tests/tests/snapshot/example/example/output/crates_turbopack-tests_tests_snapshot_example_example_input_index_838420.js.map @@ -2,6 +2,6 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/example/example/input/index.js"],"sourcesContent":["console.log(\"hello world\");\n"],"names":[],"mappings":"AAAA,QAAQ,GAAG,CAAC"}}, + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/example/example/input/index.js"],"sourcesContent":["console.log(\"hello world\");\n"],"names":[],"mappings":"AAAA,QAAQ,GAAG,CAAC"}}, {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/output/crates_turbopack-tests_tests_snapshot_export-alls_cjs-2_input_2c57a6._.js b/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/output/crates_turbopack-tests_tests_snapshot_export-alls_cjs-2_input_2c57a6._.js index 1399972b89ac3..f41bd8ed97528 100644 --- a/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/output/crates_turbopack-tests_tests_snapshot_export-alls_cjs-2_input_2c57a6._.js +++ b/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/output/crates_turbopack-tests_tests_snapshot_export-alls_cjs-2_input_2c57a6._.js @@ -1,12 +1,12 @@ (globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_export-alls_cjs-2_input_2c57a6._.js", { -"[project]/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/input/commonjs.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__, m: module, e: exports, t: require }) { !function() { +"[project]/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/input/commonjs.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { // commonjs.js exports.hello = "World"; }.call(this) }), -"[project]/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/input/c.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/input/c.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; // c.js @@ -18,7 +18,7 @@ __turbopack_dynamic__(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$ // This would be handled by existing logic })()), -"[project]/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/input/b.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/input/b.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; // b.js @@ -31,7 +31,7 @@ __turbopack_dynamic__(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$ // as there are properties dynamically added by __turbopack__cjs__ in c.js })()), -"[project]/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; // a.js diff --git a/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/output/crates_turbopack-tests_tests_snapshot_export-alls_cjs-2_input_2c57a6._.js.map b/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/output/crates_turbopack-tests_tests_snapshot_export-alls_cjs-2_input_2c57a6._.js.map index 383084dd87b95..e61d7499aae71 100644 --- a/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/output/crates_turbopack-tests_tests_snapshot_export-alls_cjs-2_input_2c57a6._.js.map +++ b/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/output/crates_turbopack-tests_tests_snapshot_export-alls_cjs-2_input_2c57a6._.js.map @@ -2,12 +2,12 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/input/commonjs.js"],"sourcesContent":["// commonjs.js\nexports.hello = \"World\";\n\n"],"names":[],"mappings":"AAAA,cAAc;AACd,QAAQ,KAAK,GAAG"}}, + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/input/commonjs.js"],"sourcesContent":["// commonjs.js\nexports.hello = \"World\";\n\n"],"names":[],"mappings":"AAAA,cAAc;AACd,QAAQ,KAAK,GAAG"}}, {"offset": {"line": 6, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 11, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/input/c.js"],"sourcesContent":["// c.js\nexport * from \"./commonjs.js\";\n// This would be handled by existing logic\n"],"names":[],"mappings":"AAAA,OAAO;;;;;;CAEP,0CAA0C"}}, + {"offset": {"line": 11, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/input/c.js"],"sourcesContent":["// c.js\nexport * from \"./commonjs.js\";\n// This would be handled by existing logic\n"],"names":[],"mappings":"AAAA,OAAO;;;;;;CAEP,0CAA0C"}}, {"offset": {"line": 18, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 23, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/input/b.js"],"sourcesContent":["// b.js\nexport * from \"./c\";\n// This would not be handled, but still need __turbopack__cjs__\n// as there are properties dynamically added by __turbopack__cjs__ in c.js\n"],"names":[],"mappings":"AAAA,OAAO;;;;;;CAEP,+DAA+D;CAC/D,0EAA0E"}}, + {"offset": {"line": 23, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/input/b.js"],"sourcesContent":["// b.js\nexport * from \"./c\";\n// This would not be handled, but still need __turbopack__cjs__\n// as there are properties dynamically added by __turbopack__cjs__ in c.js\n"],"names":[],"mappings":"AAAA,OAAO;;;;;;CAEP,+DAA+D;CAC/D,0EAA0E"}}, {"offset": {"line": 31, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 36, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/input/index.js"],"sourcesContent":["// a.js\nimport * as B from \"./b\";\nconsole.log(B);"],"names":[],"mappings":"AAAA,OAAO;;;;;AAEP,QAAQ,GAAG,CAAC"}}, + {"offset": {"line": 36, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/input/index.js"],"sourcesContent":["// a.js\nimport * as B from \"./b\";\nconsole.log(B);"],"names":[],"mappings":"AAAA,OAAO;;;;;AAEP,QAAQ,GAAG,CAAC"}}, {"offset": {"line": 42, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/export-alls/cjs-script/output/crates_turbopack-tests_tests_snapshot_export-alls_cjs-script_input_ffd38d._.js b/crates/turbopack-tests/tests/snapshot/export-alls/cjs-script/output/crates_turbopack-tests_tests_snapshot_export-alls_cjs-script_input_ffd38d._.js index f95a365904319..5d84368b21c58 100644 --- a/crates/turbopack-tests/tests/snapshot/export-alls/cjs-script/output/crates_turbopack-tests_tests_snapshot_export-alls_cjs-script_input_ffd38d._.js +++ b/crates/turbopack-tests/tests/snapshot/export-alls/cjs-script/output/crates_turbopack-tests_tests_snapshot_export-alls_cjs-script_input_ffd38d._.js @@ -1,6 +1,6 @@ (globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_export-alls_cjs-script_input_ffd38d._.js", { -"[project]/crates/turbopack-tests/tests/snapshot/export-alls/cjs-script/input/exported.cjs [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__, m: module, e: exports, t: require }) { !function() { +"[project]/crates/turbopack-tests/tests/snapshot/export-alls/cjs-script/input/exported.cjs [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { module.exports = { foo: 1, @@ -8,7 +8,7 @@ module.exports = { }; }.call(this) }), -"[project]/crates/turbopack-tests/tests/snapshot/export-alls/cjs-script/input/mod.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/export-alls/cjs-script/input/mod.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; __turbopack_esm__({}); @@ -19,7 +19,7 @@ __turbopack_dynamic__(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$ console.log('Hoist test'); })()), -"[project]/crates/turbopack-tests/tests/snapshot/export-alls/cjs-script/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/export-alls/cjs-script/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; __turbopack_esm__({}); diff --git a/crates/turbopack-tests/tests/snapshot/export-alls/cjs-script/output/crates_turbopack-tests_tests_snapshot_export-alls_cjs-script_input_ffd38d._.js.map b/crates/turbopack-tests/tests/snapshot/export-alls/cjs-script/output/crates_turbopack-tests_tests_snapshot_export-alls_cjs-script_input_ffd38d._.js.map index f557ac4143f74..ad0db65390b37 100644 --- a/crates/turbopack-tests/tests/snapshot/export-alls/cjs-script/output/crates_turbopack-tests_tests_snapshot_export-alls_cjs-script_input_ffd38d._.js.map +++ b/crates/turbopack-tests/tests/snapshot/export-alls/cjs-script/output/crates_turbopack-tests_tests_snapshot_export-alls_cjs-script_input_ffd38d._.js.map @@ -2,10 +2,10 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/export-alls/cjs-script/input/exported.cjs"],"sourcesContent":["module.exports = { foo: 1, bar: 2 }"],"names":[],"mappings":"AAAA,OAAO,OAAO,GAAG;IAAE,KAAK;IAAG,KAAK;AAAE"}}, + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/export-alls/cjs-script/input/exported.cjs"],"sourcesContent":["module.exports = { foo: 1, bar: 2 }"],"names":[],"mappings":"AAAA,OAAO,OAAO,GAAG;IAAE,KAAK;IAAG,KAAK;AAAE"}}, {"offset": {"line": 8, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 13, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/export-alls/cjs-script/input/mod.js"],"sourcesContent":["\nexport * from './exported.cjs'\n\nconsole.log('Hoist test')"],"names":[],"mappings":";;;;;AAGA,QAAQ,GAAG,CAAC"}}, + {"offset": {"line": 13, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/export-alls/cjs-script/input/mod.js"],"sourcesContent":["\nexport * from './exported.cjs'\n\nconsole.log('Hoist test')"],"names":[],"mappings":";;;;;AAGA,QAAQ,GAAG,CAAC"}}, {"offset": {"line": 19, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 24, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/export-alls/cjs-script/input/index.js"],"sourcesContent":["import * as foo from './mod.js';\n\nconsole.log(foo)"],"names":[],"mappings":";;;;AAEA,QAAQ,GAAG,CAAC"}}, + {"offset": {"line": 24, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/export-alls/cjs-script/input/index.js"],"sourcesContent":["import * as foo from './mod.js';\n\nconsole.log(foo)"],"names":[],"mappings":";;;;AAEA,QAAQ,GAAG,CAAC"}}, {"offset": {"line": 29, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/import-meta/cjs/output/crates_turbopack-tests_tests_snapshot_import-meta_cjs_input_44576c._.js b/crates/turbopack-tests/tests/snapshot/import-meta/cjs/output/crates_turbopack-tests_tests_snapshot_import-meta_cjs_input_44576c._.js index 7642a839afe74..518bc5119cadd 100644 --- a/crates/turbopack-tests/tests/snapshot/import-meta/cjs/output/crates_turbopack-tests_tests_snapshot_import-meta_cjs_input_44576c._.js +++ b/crates/turbopack-tests/tests/snapshot/import-meta/cjs/output/crates_turbopack-tests_tests_snapshot_import-meta_cjs_input_44576c._.js @@ -1,6 +1,6 @@ (globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_import-meta_cjs_input_44576c._.js", { -"[project]/crates/turbopack-tests/tests/snapshot/import-meta/cjs/input/mod.cjs [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__, m: module, e: exports, t: require }) { !function() { +"[project]/crates/turbopack-tests/tests/snapshot/import-meta/cjs/input/mod.cjs [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { const __TURBOPACK__import$2e$meta__ = { get url () { @@ -11,7 +11,7 @@ const __TURBOPACK__import$2e$meta__ = { console.log(__TURBOPACK__import$2e$meta__.url); }.call(this) }), -"[project]/crates/turbopack-tests/tests/snapshot/import-meta/cjs/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__, m: module, e: exports, t: require }) { !function() { +"[project]/crates/turbopack-tests/tests/snapshot/import-meta/cjs/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { __turbopack_esm__({}); var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$import$2d$meta$2f$cjs$2f$input$2f$mod$2e$cjs__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/import-meta/cjs/input/mod.cjs [test] (ecmascript)"); diff --git a/crates/turbopack-tests/tests/snapshot/import-meta/cjs/output/crates_turbopack-tests_tests_snapshot_import-meta_cjs_input_44576c._.js.map b/crates/turbopack-tests/tests/snapshot/import-meta/cjs/output/crates_turbopack-tests_tests_snapshot_import-meta_cjs_input_44576c._.js.map index 9e02a50ab5824..bab01750ebd87 100644 --- a/crates/turbopack-tests/tests/snapshot/import-meta/cjs/output/crates_turbopack-tests_tests_snapshot_import-meta_cjs_input_44576c._.js.map +++ b/crates/turbopack-tests/tests/snapshot/import-meta/cjs/output/crates_turbopack-tests_tests_snapshot_import-meta_cjs_input_44576c._.js.map @@ -2,7 +2,7 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/import-meta/cjs/input/mod.cjs"],"sourcesContent":["console.log(import.meta.url);\n"],"names":[],"mappings":";;;;;;AAAA,QAAQ,GAAG,CAAC,8BAAY,GAAG"}}, + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/import-meta/cjs/input/mod.cjs"],"sourcesContent":["console.log(import.meta.url);\n"],"names":[],"mappings":";;;;;;AAAA,QAAQ,GAAG,CAAC,8BAAY,GAAG"}}, {"offset": {"line": 11, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, {"offset": {"line": 15, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, {"offset": {"line": 19, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] diff --git a/crates/turbopack-tests/tests/snapshot/import-meta/esm-multiple/output/crates_turbopack-tests_tests_snapshot_import-meta_esm-multiple_input_b94ed5._.js b/crates/turbopack-tests/tests/snapshot/import-meta/esm-multiple/output/crates_turbopack-tests_tests_snapshot_import-meta_esm-multiple_input_b94ed5._.js index 4c1ce06715b79..ff8af0da07be5 100644 --- a/crates/turbopack-tests/tests/snapshot/import-meta/esm-multiple/output/crates_turbopack-tests_tests_snapshot_import-meta_esm-multiple_input_b94ed5._.js +++ b/crates/turbopack-tests/tests/snapshot/import-meta/esm-multiple/output/crates_turbopack-tests_tests_snapshot_import-meta_esm-multiple_input_b94ed5._.js @@ -1,6 +1,6 @@ (globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_import-meta_esm-multiple_input_b94ed5._.js", { -"[project]/crates/turbopack-tests/tests/snapshot/import-meta/esm-multiple/input/mod.mjs [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/import-meta/esm-multiple/input/mod.mjs [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; __turbopack_esm__({}); @@ -20,7 +20,7 @@ foo(); bar(); })()), -"[project]/crates/turbopack-tests/tests/snapshot/import-meta/esm-multiple/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__, m: module, e: exports, t: require }) { !function() { +"[project]/crates/turbopack-tests/tests/snapshot/import-meta/esm-multiple/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { __turbopack_esm__({}); var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$import$2d$meta$2f$esm$2d$multiple$2f$input$2f$mod$2e$mjs__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/import-meta/esm-multiple/input/mod.mjs [test] (ecmascript)"); diff --git a/crates/turbopack-tests/tests/snapshot/import-meta/esm-multiple/output/crates_turbopack-tests_tests_snapshot_import-meta_esm-multiple_input_b94ed5._.js.map b/crates/turbopack-tests/tests/snapshot/import-meta/esm-multiple/output/crates_turbopack-tests_tests_snapshot_import-meta_esm-multiple_input_b94ed5._.js.map index 58485640ec493..011ff7e3ee16a 100644 --- a/crates/turbopack-tests/tests/snapshot/import-meta/esm-multiple/output/crates_turbopack-tests_tests_snapshot_import-meta_esm-multiple_input_b94ed5._.js.map +++ b/crates/turbopack-tests/tests/snapshot/import-meta/esm-multiple/output/crates_turbopack-tests_tests_snapshot_import-meta_esm-multiple_input_b94ed5._.js.map @@ -2,7 +2,7 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/import-meta/esm-multiple/input/mod.mjs"],"sourcesContent":["function foo() {\n console.log(import.meta.url);\n}\nfunction bar() {\n console.log(import.meta.url);\n}\n\nfoo();\nbar();\n"],"names":[],"mappings":";;;;;;;AAAA,SAAS;IACP,QAAQ,GAAG,CAAC,8BAAY,GAAG;AAC7B;AACA,SAAS;IACP,QAAQ,GAAG,CAAC,8BAAY,GAAG;AAC7B;AAEA;AACA"}}, + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/import-meta/esm-multiple/input/mod.mjs"],"sourcesContent":["function foo() {\n console.log(import.meta.url);\n}\nfunction bar() {\n console.log(import.meta.url);\n}\n\nfoo();\nbar();\n"],"names":[],"mappings":";;;;;;;AAAA,SAAS;IACP,QAAQ,GAAG,CAAC,8BAAY,GAAG;AAC7B;AACA,SAAS;IACP,QAAQ,GAAG,CAAC,8BAAY,GAAG;AAC7B;AAEA;AACA"}}, {"offset": {"line": 20, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, {"offset": {"line": 24, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, {"offset": {"line": 28, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] diff --git a/crates/turbopack-tests/tests/snapshot/import-meta/esm-mutable/output/crates_turbopack-tests_tests_snapshot_import-meta_esm-mutable_input_f730df._.js b/crates/turbopack-tests/tests/snapshot/import-meta/esm-mutable/output/crates_turbopack-tests_tests_snapshot_import-meta_esm-mutable_input_f730df._.js index 7e8d56666e3f2..0d1bccb16cd07 100644 --- a/crates/turbopack-tests/tests/snapshot/import-meta/esm-mutable/output/crates_turbopack-tests_tests_snapshot_import-meta_esm-mutable_input_f730df._.js +++ b/crates/turbopack-tests/tests/snapshot/import-meta/esm-mutable/output/crates_turbopack-tests_tests_snapshot_import-meta_esm-mutable_input_f730df._.js @@ -1,6 +1,6 @@ (globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_import-meta_esm-mutable_input_f730df._.js", { -"[project]/crates/turbopack-tests/tests/snapshot/import-meta/esm-mutable/input/mod.mjs [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/import-meta/esm-mutable/input/mod.mjs [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; __turbopack_esm__({}); @@ -13,7 +13,7 @@ const __TURBOPACK__import$2e$meta__ = { __TURBOPACK__import$2e$meta__.foo = 1; })()), -"[project]/crates/turbopack-tests/tests/snapshot/import-meta/esm-mutable/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__, m: module, e: exports, t: require }) { !function() { +"[project]/crates/turbopack-tests/tests/snapshot/import-meta/esm-mutable/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { __turbopack_esm__({}); var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$import$2d$meta$2f$esm$2d$mutable$2f$input$2f$mod$2e$mjs__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/import-meta/esm-mutable/input/mod.mjs [test] (ecmascript)"); diff --git a/crates/turbopack-tests/tests/snapshot/import-meta/esm-mutable/output/crates_turbopack-tests_tests_snapshot_import-meta_esm-mutable_input_f730df._.js.map b/crates/turbopack-tests/tests/snapshot/import-meta/esm-mutable/output/crates_turbopack-tests_tests_snapshot_import-meta_esm-mutable_input_f730df._.js.map index b8b808937ad8e..a5ea31f14260c 100644 --- a/crates/turbopack-tests/tests/snapshot/import-meta/esm-mutable/output/crates_turbopack-tests_tests_snapshot_import-meta_esm-mutable_input_f730df._.js.map +++ b/crates/turbopack-tests/tests/snapshot/import-meta/esm-mutable/output/crates_turbopack-tests_tests_snapshot_import-meta_esm-mutable_input_f730df._.js.map @@ -2,7 +2,7 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/import-meta/esm-mutable/input/mod.mjs"],"sourcesContent":["import.meta.foo = 1;\n"],"names":[],"mappings":";;;;;;;AAAA,8BAAY,GAAG,GAAG"}}, + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/import-meta/esm-mutable/input/mod.mjs"],"sourcesContent":["import.meta.foo = 1;\n"],"names":[],"mappings":";;;;;;;AAAA,8BAAY,GAAG,GAAG"}}, {"offset": {"line": 13, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, {"offset": {"line": 17, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, {"offset": {"line": 21, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] diff --git a/crates/turbopack-tests/tests/snapshot/import-meta/esm-object/output/crates_turbopack-tests_tests_snapshot_import-meta_esm-object_input_51cbdd._.js b/crates/turbopack-tests/tests/snapshot/import-meta/esm-object/output/crates_turbopack-tests_tests_snapshot_import-meta_esm-object_input_51cbdd._.js index 3b1aaf498d36f..f88f6b8b174a9 100644 --- a/crates/turbopack-tests/tests/snapshot/import-meta/esm-object/output/crates_turbopack-tests_tests_snapshot_import-meta_esm-object_input_51cbdd._.js +++ b/crates/turbopack-tests/tests/snapshot/import-meta/esm-object/output/crates_turbopack-tests_tests_snapshot_import-meta_esm-object_input_51cbdd._.js @@ -1,6 +1,6 @@ (globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_import-meta_esm-object_input_51cbdd._.js", { -"[project]/crates/turbopack-tests/tests/snapshot/import-meta/esm-object/input/mod.mjs [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/import-meta/esm-object/input/mod.mjs [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; __turbopack_esm__({}); @@ -13,7 +13,7 @@ const __TURBOPACK__import$2e$meta__ = { console.log(__TURBOPACK__import$2e$meta__); })()), -"[project]/crates/turbopack-tests/tests/snapshot/import-meta/esm-object/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__, m: module, e: exports, t: require }) { !function() { +"[project]/crates/turbopack-tests/tests/snapshot/import-meta/esm-object/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { __turbopack_esm__({}); var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$import$2d$meta$2f$esm$2d$object$2f$input$2f$mod$2e$mjs__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/import-meta/esm-object/input/mod.mjs [test] (ecmascript)"); diff --git a/crates/turbopack-tests/tests/snapshot/import-meta/esm-object/output/crates_turbopack-tests_tests_snapshot_import-meta_esm-object_input_51cbdd._.js.map b/crates/turbopack-tests/tests/snapshot/import-meta/esm-object/output/crates_turbopack-tests_tests_snapshot_import-meta_esm-object_input_51cbdd._.js.map index f03ea024d250c..712b8657fe4c8 100644 --- a/crates/turbopack-tests/tests/snapshot/import-meta/esm-object/output/crates_turbopack-tests_tests_snapshot_import-meta_esm-object_input_51cbdd._.js.map +++ b/crates/turbopack-tests/tests/snapshot/import-meta/esm-object/output/crates_turbopack-tests_tests_snapshot_import-meta_esm-object_input_51cbdd._.js.map @@ -2,7 +2,7 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/import-meta/esm-object/input/mod.mjs"],"sourcesContent":["console.log(import.meta);\n"],"names":[],"mappings":";;;;;;;AAAA,QAAQ,GAAG"}}, + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/import-meta/esm-object/input/mod.mjs"],"sourcesContent":["console.log(import.meta);\n"],"names":[],"mappings":";;;;;;;AAAA,QAAQ,GAAG"}}, {"offset": {"line": 13, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, {"offset": {"line": 17, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, {"offset": {"line": 21, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] diff --git a/crates/turbopack-tests/tests/snapshot/import-meta/esm/output/crates_turbopack-tests_tests_snapshot_import-meta_esm_input_5f2592._.js b/crates/turbopack-tests/tests/snapshot/import-meta/esm/output/crates_turbopack-tests_tests_snapshot_import-meta_esm_input_5f2592._.js index f03dd4778579b..4efa689fcd239 100644 --- a/crates/turbopack-tests/tests/snapshot/import-meta/esm/output/crates_turbopack-tests_tests_snapshot_import-meta_esm_input_5f2592._.js +++ b/crates/turbopack-tests/tests/snapshot/import-meta/esm/output/crates_turbopack-tests_tests_snapshot_import-meta_esm_input_5f2592._.js @@ -1,6 +1,6 @@ (globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_import-meta_esm_input_5f2592._.js", { -"[project]/crates/turbopack-tests/tests/snapshot/import-meta/esm/input/mod.mjs [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/import-meta/esm/input/mod.mjs [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; __turbopack_esm__({}); @@ -13,7 +13,7 @@ const __TURBOPACK__import$2e$meta__ = { console.log(__TURBOPACK__import$2e$meta__.url); })()), -"[project]/crates/turbopack-tests/tests/snapshot/import-meta/esm/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__, m: module, e: exports, t: require }) { !function() { +"[project]/crates/turbopack-tests/tests/snapshot/import-meta/esm/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { __turbopack_esm__({}); var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$import$2d$meta$2f$esm$2f$input$2f$mod$2e$mjs__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/import-meta/esm/input/mod.mjs [test] (ecmascript)"); diff --git a/crates/turbopack-tests/tests/snapshot/import-meta/esm/output/crates_turbopack-tests_tests_snapshot_import-meta_esm_input_5f2592._.js.map b/crates/turbopack-tests/tests/snapshot/import-meta/esm/output/crates_turbopack-tests_tests_snapshot_import-meta_esm_input_5f2592._.js.map index 18c45b2eea975..b308c4de546ba 100644 --- a/crates/turbopack-tests/tests/snapshot/import-meta/esm/output/crates_turbopack-tests_tests_snapshot_import-meta_esm_input_5f2592._.js.map +++ b/crates/turbopack-tests/tests/snapshot/import-meta/esm/output/crates_turbopack-tests_tests_snapshot_import-meta_esm_input_5f2592._.js.map @@ -2,7 +2,7 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/import-meta/esm/input/mod.mjs"],"sourcesContent":["console.log(import.meta.url);\n"],"names":[],"mappings":";;;;;;;AAAA,QAAQ,GAAG,CAAC,8BAAY,GAAG"}}, + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/import-meta/esm/input/mod.mjs"],"sourcesContent":["console.log(import.meta.url);\n"],"names":[],"mappings":";;;;;;;AAAA,QAAQ,GAAG,CAAC,8BAAY,GAAG"}}, {"offset": {"line": 13, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, {"offset": {"line": 17, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, {"offset": {"line": 21, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] diff --git a/crates/turbopack-tests/tests/snapshot/import-meta/url/output/crates_turbopack-tests_tests_snapshot_import-meta_url_input_9b6f5c._.js b/crates/turbopack-tests/tests/snapshot/import-meta/url/output/crates_turbopack-tests_tests_snapshot_import-meta_url_input_9b6f5c._.js index 68ab1cc9d1d6b..ba6d48e54ae3a 100644 --- a/crates/turbopack-tests/tests/snapshot/import-meta/url/output/crates_turbopack-tests_tests_snapshot_import-meta_url_input_9b6f5c._.js +++ b/crates/turbopack-tests/tests/snapshot/import-meta/url/output/crates_turbopack-tests_tests_snapshot_import-meta_url_input_9b6f5c._.js @@ -4,7 +4,7 @@ __turbopack_export_value__("/static/asset.05254cf2.txt"); })()), -"[project]/crates/turbopack-tests/tests/snapshot/import-meta/url/input/mod.mjs [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/import-meta/url/input/mod.mjs [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; __turbopack_esm__({}); @@ -19,7 +19,7 @@ console.log(assetUrl); fetch(assetUrl).then((res)=>res.text()).then(console.log); })()), -"[project]/crates/turbopack-tests/tests/snapshot/import-meta/url/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__, m: module, e: exports, t: require }) { !function() { +"[project]/crates/turbopack-tests/tests/snapshot/import-meta/url/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { __turbopack_esm__({}); var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$import$2d$meta$2f$url$2f$input$2f$mod$2e$mjs__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/import-meta/url/input/mod.mjs [test] (ecmascript)"); diff --git a/crates/turbopack-tests/tests/snapshot/import-meta/url/output/crates_turbopack-tests_tests_snapshot_import-meta_url_input_9b6f5c._.js.map b/crates/turbopack-tests/tests/snapshot/import-meta/url/output/crates_turbopack-tests_tests_snapshot_import-meta_url_input_9b6f5c._.js.map index eff4e802bcbfb..20641d5b665cd 100644 --- a/crates/turbopack-tests/tests/snapshot/import-meta/url/output/crates_turbopack-tests_tests_snapshot_import-meta_url_input_9b6f5c._.js.map +++ b/crates/turbopack-tests/tests/snapshot/import-meta/url/output/crates_turbopack-tests_tests_snapshot_import-meta_url_input_9b6f5c._.js.map @@ -2,7 +2,7 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 9, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/import-meta/url/input/mod.mjs"],"sourcesContent":["const assetUrl = new URL('./asset.txt', import.meta.url);\n\nconsole.log(assetUrl);\nfetch(assetUrl)\n .then(res => res.text())\n .then(console.log);\n"],"names":[],"mappings":";;;;;;;AAAA,MAAM;AAEN,QAAQ,GAAG,CAAC;AACZ,MAAM,UACH,IAAI,CAAC,CAAA,MAAO,IAAI,IAAI,IACpB,IAAI,CAAC,QAAQ,GAAG"}}, + {"offset": {"line": 9, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/import-meta/url/input/mod.mjs"],"sourcesContent":["const assetUrl = new URL('./asset.txt', import.meta.url);\n\nconsole.log(assetUrl);\nfetch(assetUrl)\n .then(res => res.text())\n .then(console.log);\n"],"names":[],"mappings":";;;;;;;AAAA,MAAM;AAEN,QAAQ,GAAG,CAAC;AACZ,MAAM,UACH,IAAI,CAAC,CAAA,MAAO,IAAI,IAAI,IACpB,IAAI,CAAC,QAAQ,GAAG"}}, {"offset": {"line": 19, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, {"offset": {"line": 23, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, {"offset": {"line": 27, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] diff --git a/crates/turbopack-tests/tests/snapshot/imports/duplicate-binding/output/crates_turbopack-tests_tests_snapshot_imports_duplicate-binding_input_9ca1ac._.js b/crates/turbopack-tests/tests/snapshot/imports/duplicate-binding/output/crates_turbopack-tests_tests_snapshot_imports_duplicate-binding_input_9ca1ac._.js index d28ac303209f4..efa5e92b6d837 100644 --- a/crates/turbopack-tests/tests/snapshot/imports/duplicate-binding/output/crates_turbopack-tests_tests_snapshot_imports_duplicate-binding_input_9ca1ac._.js +++ b/crates/turbopack-tests/tests/snapshot/imports/duplicate-binding/output/crates_turbopack-tests_tests_snapshot_imports_duplicate-binding_input_9ca1ac._.js @@ -1,6 +1,6 @@ (globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_imports_duplicate-binding_input_9ca1ac._.js", { -"[project]/crates/turbopack-tests/tests/snapshot/imports/duplicate-binding/input/table.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/imports/duplicate-binding/input/table.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; __turbopack_esm__({ @@ -11,7 +11,7 @@ const Table = ()=>{ }; })()), -"[project]/crates/turbopack-tests/tests/snapshot/imports/duplicate-binding/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/imports/duplicate-binding/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; __turbopack_esm__({ diff --git a/crates/turbopack-tests/tests/snapshot/imports/duplicate-binding/output/crates_turbopack-tests_tests_snapshot_imports_duplicate-binding_input_9ca1ac._.js.map b/crates/turbopack-tests/tests/snapshot/imports/duplicate-binding/output/crates_turbopack-tests_tests_snapshot_imports_duplicate-binding_input_9ca1ac._.js.map index 4e5b26117d3d3..8eb4573580dd6 100644 --- a/crates/turbopack-tests/tests/snapshot/imports/duplicate-binding/output/crates_turbopack-tests_tests_snapshot_imports_duplicate-binding_input_9ca1ac._.js.map +++ b/crates/turbopack-tests/tests/snapshot/imports/duplicate-binding/output/crates_turbopack-tests_tests_snapshot_imports_duplicate-binding_input_9ca1ac._.js.map @@ -2,8 +2,8 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/imports/duplicate-binding/input/table.js"],"sourcesContent":["export const Table = ()=>{\n return 'table'\n}\n"],"names":[],"mappings":";;;AAAO,MAAM,QAAQ;IACnB,OAAO;AACT"}}, + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/imports/duplicate-binding/input/table.js"],"sourcesContent":["export const Table = ()=>{\n return 'table'\n}\n"],"names":[],"mappings":";;;AAAO,MAAM,QAAQ;IACnB,OAAO;AACT"}}, {"offset": {"line": 11, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 16, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/imports/duplicate-binding/input/index.js"],"sourcesContent":["\nimport { Table } from \"./table\"\n\nexport function Table() {\n console.log(Table)\n}\n"],"names":[],"mappings":";;;;;;AAGO,SAAS;IACZ,QAAQ,GAAG,CAAC,gMAAA,CAAA,QAAK;AACrB"}}, + {"offset": {"line": 16, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/imports/duplicate-binding/input/index.js"],"sourcesContent":["\nimport { Table } from \"./table\"\n\nexport function Table() {\n console.log(Table)\n}\n"],"names":[],"mappings":";;;;;;AAGO,SAAS;IACZ,QAAQ,GAAG,CAAC,gMAAA,CAAA,QAAK;AACrB"}}, {"offset": {"line": 25, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/imports/dynamic/output/crates_turbopack-tests_tests_snapshot_imports_dynamic_input_index_5ee1a4.js b/crates/turbopack-tests/tests/snapshot/imports/dynamic/output/crates_turbopack-tests_tests_snapshot_imports_dynamic_input_index_5ee1a4.js index ae0c33805279d..38f0c13f2007b 100644 --- a/crates/turbopack-tests/tests/snapshot/imports/dynamic/output/crates_turbopack-tests_tests_snapshot_imports_dynamic_input_index_5ee1a4.js +++ b/crates/turbopack-tests/tests/snapshot/imports/dynamic/output/crates_turbopack-tests_tests_snapshot_imports_dynamic_input_index_5ee1a4.js @@ -1,6 +1,6 @@ (globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_imports_dynamic_input_index_5ee1a4.js", { -"[project]/crates/turbopack-tests/tests/snapshot/imports/dynamic/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__, m: module, e: exports, t: require }) { !function() { +"[project]/crates/turbopack-tests/tests/snapshot/imports/dynamic/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { __turbopack_require__("[project]/crates/turbopack-tests/tests/snapshot/imports/dynamic/input/vercel.mjs [test] (ecmascript, async loader)")(__turbopack_import__).then(console.log); diff --git a/crates/turbopack-tests/tests/snapshot/imports/dynamic/output/crates_turbopack-tests_tests_snapshot_imports_dynamic_input_index_5ee1a4.js.map b/crates/turbopack-tests/tests/snapshot/imports/dynamic/output/crates_turbopack-tests_tests_snapshot_imports_dynamic_input_index_5ee1a4.js.map index 950a72acad14f..6afa602b1df84 100644 --- a/crates/turbopack-tests/tests/snapshot/imports/dynamic/output/crates_turbopack-tests_tests_snapshot_imports_dynamic_input_index_5ee1a4.js.map +++ b/crates/turbopack-tests/tests/snapshot/imports/dynamic/output/crates_turbopack-tests_tests_snapshot_imports_dynamic_input_index_5ee1a4.js.map @@ -2,6 +2,6 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/imports/dynamic/input/index.js"],"sourcesContent":["import(\"./vercel.mjs\").then(console.log);\n"],"names":[],"mappings":"AAAA,kKAAuB,IAAI,CAAC,QAAQ,GAAG"}}, + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/imports/dynamic/input/index.js"],"sourcesContent":["import(\"./vercel.mjs\").then(console.log);\n"],"names":[],"mappings":"AAAA,kKAAuB,IAAI,CAAC,QAAQ,GAAG"}}, {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/imports/dynamic/output/crates_turbopack-tests_tests_snapshot_imports_dynamic_input_vercel_mjs_18521c._.js b/crates/turbopack-tests/tests/snapshot/imports/dynamic/output/crates_turbopack-tests_tests_snapshot_imports_dynamic_input_vercel_mjs_18521c._.js index dcf9a5cec3e3f..3dc2389de4d87 100644 --- a/crates/turbopack-tests/tests/snapshot/imports/dynamic/output/crates_turbopack-tests_tests_snapshot_imports_dynamic_input_vercel_mjs_18521c._.js +++ b/crates/turbopack-tests/tests/snapshot/imports/dynamic/output/crates_turbopack-tests_tests_snapshot_imports_dynamic_input_vercel_mjs_18521c._.js @@ -1,6 +1,6 @@ (globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_imports_dynamic_input_vercel_mjs_18521c._.js", { -"[project]/crates/turbopack-tests/tests/snapshot/imports/dynamic/input/vercel.mjs [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/imports/dynamic/input/vercel.mjs [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; __turbopack_esm__({ diff --git a/crates/turbopack-tests/tests/snapshot/imports/dynamic/output/crates_turbopack-tests_tests_snapshot_imports_dynamic_input_vercel_mjs_18521c._.js.map b/crates/turbopack-tests/tests/snapshot/imports/dynamic/output/crates_turbopack-tests_tests_snapshot_imports_dynamic_input_vercel_mjs_18521c._.js.map index 2d827f2e2506c..794f5d5dae28e 100644 --- a/crates/turbopack-tests/tests/snapshot/imports/dynamic/output/crates_turbopack-tests_tests_snapshot_imports_dynamic_input_vercel_mjs_18521c._.js.map +++ b/crates/turbopack-tests/tests/snapshot/imports/dynamic/output/crates_turbopack-tests_tests_snapshot_imports_dynamic_input_vercel_mjs_18521c._.js.map @@ -2,6 +2,6 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/imports/dynamic/input/vercel.mjs"],"sourcesContent":["export default \"turbopack\";\n"],"names":[],"mappings":";;;uCAAe"}}, + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/imports/dynamic/input/vercel.mjs"],"sourcesContent":["export default \"turbopack\";\n"],"names":[],"mappings":";;;uCAAe"}}, {"offset": {"line": 9, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/imports/json/output/crates_turbopack-tests_tests_snapshot_imports_json_input_22bb62._.js b/crates/turbopack-tests/tests/snapshot/imports/json/output/crates_turbopack-tests_tests_snapshot_imports_json_input_22bb62._.js index c79559cf59e96..81aaeb6bb53ca 100644 --- a/crates/turbopack-tests/tests/snapshot/imports/json/output/crates_turbopack-tests_tests_snapshot_imports_json_input_22bb62._.js +++ b/crates/turbopack-tests/tests/snapshot/imports/json/output/crates_turbopack-tests_tests_snapshot_imports_json_input_22bb62._.js @@ -9,7 +9,7 @@ __turbopack_export_value__(JSON.parse("{\"name\":\"json-snapshot\"}")); throw new Error("An error occurred while generating the chunk item [project]/crates/turbopack-tests/tests/snapshot/imports/json/input/invalid.json (json)\n\nCaused by:\n- Unable to make a module from invalid JSON: expected `,` or `}` at line 3 column 26\n\nDebug info:\n- An error occurred while generating the chunk item [project]/crates/turbopack-tests/tests/snapshot/imports/json/input/invalid.json (json)\n- Execution of EcmascriptChunkItemContent::module_factory failed\n- Execution of ::content failed\n- Unable to make a module from invalid JSON: expected `,` or `}` at line 3 column 26\n at nested.?\n 1 | {\n 2 | \"nested\": {\n | v\n 3 + \"this-is\": \"invalid\" // lint-staged will remove trailing commas, so here's a comment\n | ^\n 4 | }\n 5 | }"); }}), -"[project]/crates/turbopack-tests/tests/snapshot/imports/json/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/imports/json/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; __turbopack_esm__({}); diff --git a/crates/turbopack-tests/tests/snapshot/imports/json/output/crates_turbopack-tests_tests_snapshot_imports_json_input_22bb62._.js.map b/crates/turbopack-tests/tests/snapshot/imports/json/output/crates_turbopack-tests_tests_snapshot_imports_json_input_22bb62._.js.map index 8191df39d144b..8affe11a79ec9 100644 --- a/crates/turbopack-tests/tests/snapshot/imports/json/output/crates_turbopack-tests_tests_snapshot_imports_json_input_22bb62._.js.map +++ b/crates/turbopack-tests/tests/snapshot/imports/json/output/crates_turbopack-tests_tests_snapshot_imports_json_input_22bb62._.js.map @@ -2,6 +2,6 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 14, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/imports/json/input/index.js"],"sourcesContent":["import pkg from \"./package.json\";\nconsole.log(pkg.name);\nimport invalid from \"./invalid.json\";\nconsole.log(invalid[\"this-is\"]);\n"],"names":[],"mappings":";;;;;AACA,QAAQ,GAAG,CAAC,gKAAA,CAAA,UAAG,CAAC,IAAI;;AAEpB,QAAQ,GAAG,CAAC,gKAAA,CAAA,UAAO,CAAC,UAAU"}}, + {"offset": {"line": 14, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/imports/json/input/index.js"],"sourcesContent":["import pkg from \"./package.json\";\nconsole.log(pkg.name);\nimport invalid from \"./invalid.json\";\nconsole.log(invalid[\"this-is\"]);\n"],"names":[],"mappings":";;;;;AACA,QAAQ,GAAG,CAAC,gKAAA,CAAA,UAAG,CAAC,IAAI;;AAEpB,QAAQ,GAAG,CAAC,gKAAA,CAAA,UAAO,CAAC,UAAU"}}, {"offset": {"line": 22, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/imports/order/output/crates_turbopack-tests_tests_snapshot_imports_order_input_c5b1db._.js b/crates/turbopack-tests/tests/snapshot/imports/order/output/crates_turbopack-tests_tests_snapshot_imports_order_input_c5b1db._.js index 1f8e67609797a..e615a1e30e205 100644 --- a/crates/turbopack-tests/tests/snapshot/imports/order/output/crates_turbopack-tests_tests_snapshot_imports_order_input_c5b1db._.js +++ b/crates/turbopack-tests/tests/snapshot/imports/order/output/crates_turbopack-tests_tests_snapshot_imports_order_input_c5b1db._.js @@ -1,6 +1,6 @@ (globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_imports_order_input_c5b1db._.js", { -"[project]/crates/turbopack-tests/tests/snapshot/imports/order/input/posts.ts [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/imports/order/input/posts.ts [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; __turbopack_esm__({ @@ -11,7 +11,7 @@ const __TURBOPACK__default__export__ = { }; })()), -"[project]/crates/turbopack-tests/tests/snapshot/imports/order/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/imports/order/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; __turbopack_esm__({}); diff --git a/crates/turbopack-tests/tests/snapshot/imports/order/output/crates_turbopack-tests_tests_snapshot_imports_order_input_c5b1db._.js.map b/crates/turbopack-tests/tests/snapshot/imports/order/output/crates_turbopack-tests_tests_snapshot_imports_order_input_c5b1db._.js.map index dd7de115c537d..08eb3b36a73b8 100644 --- a/crates/turbopack-tests/tests/snapshot/imports/order/output/crates_turbopack-tests_tests_snapshot_imports_order_input_c5b1db._.js.map +++ b/crates/turbopack-tests/tests/snapshot/imports/order/output/crates_turbopack-tests_tests_snapshot_imports_order_input_c5b1db._.js.map @@ -2,8 +2,8 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/imports/order/input/posts.ts"],"sourcesContent":["export default {\n js: true,\n};\n"],"names":[],"mappings":";;;uCAAe;IACb,IAAI;AACN"}}, + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/imports/order/input/posts.ts"],"sourcesContent":["export default {\n js: true,\n};\n"],"names":[],"mappings":";;;uCAAe;IACb,IAAI;AACN"}}, {"offset": {"line": 11, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 16, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/imports/order/input/index.js"],"sourcesContent":["import posts from \"./posts\";\n\nconsole.log(posts.js);\nif (!posts.js) {\n process.exit(1);\n}\n"],"names":[],"mappings":";;;;AAEA,QAAQ,GAAG,CAAC,iLAAA,CAAA,UAAK,CAAC,EAAE;AACpB,IAAI,CAAC,iLAAA,CAAA,UAAK,CAAC,EAAE,EAAE;IACb,QAAQ,IAAI,CAAC;AACf"}}, + {"offset": {"line": 16, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/imports/order/input/index.js"],"sourcesContent":["import posts from \"./posts\";\n\nconsole.log(posts.js);\nif (!posts.js) {\n process.exit(1);\n}\n"],"names":[],"mappings":";;;;AAEA,QAAQ,GAAG,CAAC,iLAAA,CAAA,UAAK,CAAC,EAAE;AACpB,IAAI,CAAC,iLAAA,CAAA,UAAK,CAAC,EAAE,EAAE;IACb,QAAQ,IAAI,CAAC;AACf"}}, {"offset": {"line": 24, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/imports/resolve_error_cjs/output/79fb1_turbopack-tests_tests_snapshot_imports_resolve_error_cjs_input_index_86e786.js b/crates/turbopack-tests/tests/snapshot/imports/resolve_error_cjs/output/79fb1_turbopack-tests_tests_snapshot_imports_resolve_error_cjs_input_index_86e786.js index 12c008756f772..c69036142b68f 100644 --- a/crates/turbopack-tests/tests/snapshot/imports/resolve_error_cjs/output/79fb1_turbopack-tests_tests_snapshot_imports_resolve_error_cjs_input_index_86e786.js +++ b/crates/turbopack-tests/tests/snapshot/imports/resolve_error_cjs/output/79fb1_turbopack-tests_tests_snapshot_imports_resolve_error_cjs_input_index_86e786.js @@ -1,6 +1,6 @@ (globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/79fb1_turbopack-tests_tests_snapshot_imports_resolve_error_cjs_input_index_86e786.js", { -"[project]/crates/turbopack-tests/tests/snapshot/imports/resolve_error_cjs/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__, m: module, e: exports, t: require }) { !function() { +"[project]/crates/turbopack-tests/tests/snapshot/imports/resolve_error_cjs/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { const dne = (()=>{ const e = new Error("Cannot find module 'does-not-exist/path'"); diff --git a/crates/turbopack-tests/tests/snapshot/imports/resolve_error_cjs/output/79fb1_turbopack-tests_tests_snapshot_imports_resolve_error_cjs_input_index_86e786.js.map b/crates/turbopack-tests/tests/snapshot/imports/resolve_error_cjs/output/79fb1_turbopack-tests_tests_snapshot_imports_resolve_error_cjs_input_index_86e786.js.map index 48593daf18f5c..e4e9373c6763e 100644 --- a/crates/turbopack-tests/tests/snapshot/imports/resolve_error_cjs/output/79fb1_turbopack-tests_tests_snapshot_imports_resolve_error_cjs_input_index_86e786.js.map +++ b/crates/turbopack-tests/tests/snapshot/imports/resolve_error_cjs/output/79fb1_turbopack-tests_tests_snapshot_imports_resolve_error_cjs_input_index_86e786.js.map @@ -2,6 +2,6 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/imports/resolve_error_cjs/input/index.js"],"sourcesContent":["const dne = require(\"does-not-exist/path\");\n\nconsole.log(dne);\n"],"names":[],"mappings":"AAAA,MAAM;;;;;AAEN,QAAQ,GAAG,CAAC"}}, + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/imports/resolve_error_cjs/input/index.js"],"sourcesContent":["const dne = require(\"does-not-exist/path\");\n\nconsole.log(dne);\n"],"names":[],"mappings":"AAAA,MAAM;;;;;AAEN,QAAQ,GAAG,CAAC"}}, {"offset": {"line": 10, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/imports/resolve_error_esm/output/79fb1_turbopack-tests_tests_snapshot_imports_resolve_error_esm_input_index_c7ccd7.js b/crates/turbopack-tests/tests/snapshot/imports/resolve_error_esm/output/79fb1_turbopack-tests_tests_snapshot_imports_resolve_error_esm_input_index_c7ccd7.js index fb2c83382c824..2004a41c60091 100644 --- a/crates/turbopack-tests/tests/snapshot/imports/resolve_error_esm/output/79fb1_turbopack-tests_tests_snapshot_imports_resolve_error_esm_input_index_c7ccd7.js +++ b/crates/turbopack-tests/tests/snapshot/imports/resolve_error_esm/output/79fb1_turbopack-tests_tests_snapshot_imports_resolve_error_esm_input_index_c7ccd7.js @@ -1,6 +1,6 @@ (globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/79fb1_turbopack-tests_tests_snapshot_imports_resolve_error_esm_input_index_c7ccd7.js", { -"[project]/crates/turbopack-tests/tests/snapshot/imports/resolve_error_esm/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/imports/resolve_error_esm/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; __turbopack_esm__({}); diff --git a/crates/turbopack-tests/tests/snapshot/imports/resolve_error_esm/output/79fb1_turbopack-tests_tests_snapshot_imports_resolve_error_esm_input_index_c7ccd7.js.map b/crates/turbopack-tests/tests/snapshot/imports/resolve_error_esm/output/79fb1_turbopack-tests_tests_snapshot_imports_resolve_error_esm_input_index_c7ccd7.js.map index 5c68953d0e2c6..c4850dcda61ae 100644 --- a/crates/turbopack-tests/tests/snapshot/imports/resolve_error_esm/output/79fb1_turbopack-tests_tests_snapshot_imports_resolve_error_esm_input_index_c7ccd7.js.map +++ b/crates/turbopack-tests/tests/snapshot/imports/resolve_error_esm/output/79fb1_turbopack-tests_tests_snapshot_imports_resolve_error_esm_input_index_c7ccd7.js.map @@ -2,6 +2,6 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/imports/resolve_error_esm/input/index.js"],"sourcesContent":["import dne from \"does-not-exist/path\";\n\nconsole.log(dne);\nconsole.log({}[dne]);\n"],"names":[],"mappings":";;;;;;;;AAEA,QAAQ,GAAG,CAAC;AACZ,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI"}}, + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/imports/resolve_error_esm/input/index.js"],"sourcesContent":["import dne from \"does-not-exist/path\";\n\nconsole.log(dne);\nconsole.log({}[dne]);\n"],"names":[],"mappings":";;;;;;;;AAEA,QAAQ,GAAG,CAAC;AACZ,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI"}}, {"offset": {"line": 15, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/imports/static-and-dynamic/output/crates_turbopack-tests_tests_snapshot_imports_static-and-dynamic_input_cbb273._.js b/crates/turbopack-tests/tests/snapshot/imports/static-and-dynamic/output/crates_turbopack-tests_tests_snapshot_imports_static-and-dynamic_input_cbb273._.js index b1299401a5191..dbb3bbfd770fc 100644 --- a/crates/turbopack-tests/tests/snapshot/imports/static-and-dynamic/output/crates_turbopack-tests_tests_snapshot_imports_static-and-dynamic_input_cbb273._.js +++ b/crates/turbopack-tests/tests/snapshot/imports/static-and-dynamic/output/crates_turbopack-tests_tests_snapshot_imports_static-and-dynamic_input_cbb273._.js @@ -1,6 +1,6 @@ (globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_imports_static-and-dynamic_input_cbb273._.js", { -"[project]/crates/turbopack-tests/tests/snapshot/imports/static-and-dynamic/input/vercel.mjs [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/imports/static-and-dynamic/input/vercel.mjs [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; __turbopack_esm__({ @@ -9,7 +9,7 @@ __turbopack_esm__({ const __TURBOPACK__default__export__ = "turbopack"; })()), -"[project]/crates/turbopack-tests/tests/snapshot/imports/static-and-dynamic/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/imports/static-and-dynamic/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; __turbopack_esm__({}); diff --git a/crates/turbopack-tests/tests/snapshot/imports/static-and-dynamic/output/crates_turbopack-tests_tests_snapshot_imports_static-and-dynamic_input_cbb273._.js.map b/crates/turbopack-tests/tests/snapshot/imports/static-and-dynamic/output/crates_turbopack-tests_tests_snapshot_imports_static-and-dynamic_input_cbb273._.js.map index bed6960dba585..4c606d3b86870 100644 --- a/crates/turbopack-tests/tests/snapshot/imports/static-and-dynamic/output/crates_turbopack-tests_tests_snapshot_imports_static-and-dynamic_input_cbb273._.js.map +++ b/crates/turbopack-tests/tests/snapshot/imports/static-and-dynamic/output/crates_turbopack-tests_tests_snapshot_imports_static-and-dynamic_input_cbb273._.js.map @@ -2,8 +2,8 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/imports/static-and-dynamic/input/vercel.mjs"],"sourcesContent":["export default \"turbopack\";\n"],"names":[],"mappings":";;;uCAAe"}}, + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/imports/static-and-dynamic/input/vercel.mjs"],"sourcesContent":["export default \"turbopack\";\n"],"names":[],"mappings":";;;uCAAe"}}, {"offset": {"line": 9, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 14, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/imports/static-and-dynamic/input/index.js"],"sourcesContent":["import img from \"./vercel.mjs\";\nconsole.log(img);\n\nimport(\"./vercel.mjs\").then(console.log);\n"],"names":[],"mappings":";;;;AACA,QAAQ,GAAG,CAAC,sMAAA,CAAA,UAAG;AAEf,6KAAuB,IAAI,CAAC,QAAQ,GAAG"}}, + {"offset": {"line": 14, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/imports/static-and-dynamic/input/index.js"],"sourcesContent":["import img from \"./vercel.mjs\";\nconsole.log(img);\n\nimport(\"./vercel.mjs\").then(console.log);\n"],"names":[],"mappings":";;;;AACA,QAAQ,GAAG,CAAC,sMAAA,CAAA,UAAG;AAEf,6KAAuB,IAAI,CAAC,QAAQ,GAAG"}}, {"offset": {"line": 20, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/imports/static/output/crates_turbopack-tests_tests_snapshot_imports_static_input_4175d9._.js b/crates/turbopack-tests/tests/snapshot/imports/static/output/crates_turbopack-tests_tests_snapshot_imports_static_input_4175d9._.js index c543a90679529..59fba5f79929e 100644 --- a/crates/turbopack-tests/tests/snapshot/imports/static/output/crates_turbopack-tests_tests_snapshot_imports_static_input_4175d9._.js +++ b/crates/turbopack-tests/tests/snapshot/imports/static/output/crates_turbopack-tests_tests_snapshot_imports_static_input_4175d9._.js @@ -4,7 +4,7 @@ __turbopack_export_value__("/static/vercel.957b9b16.svg"); })()), -"[project]/crates/turbopack-tests/tests/snapshot/imports/static/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/imports/static/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; __turbopack_esm__({}); diff --git a/crates/turbopack-tests/tests/snapshot/imports/static/output/crates_turbopack-tests_tests_snapshot_imports_static_input_4175d9._.js.map b/crates/turbopack-tests/tests/snapshot/imports/static/output/crates_turbopack-tests_tests_snapshot_imports_static_input_4175d9._.js.map index 7f432df331cbc..5e64d30ea2871 100644 --- a/crates/turbopack-tests/tests/snapshot/imports/static/output/crates_turbopack-tests_tests_snapshot_imports_static_input_4175d9._.js.map +++ b/crates/turbopack-tests/tests/snapshot/imports/static/output/crates_turbopack-tests_tests_snapshot_imports_static_input_4175d9._.js.map @@ -2,6 +2,6 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 9, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/imports/static/input/index.js"],"sourcesContent":["import img from \"./vercel.svg\";\nconsole.log(img);\n"],"names":[],"mappings":";;;;AACA,QAAQ,GAAG,CAAC,gLAAA,CAAA,UAAG"}}, + {"offset": {"line": 9, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/imports/static/input/index.js"],"sourcesContent":["import img from \"./vercel.svg\";\nconsole.log(img);\n"],"names":[],"mappings":";;;;AACA,QAAQ,GAAG,CAAC,gLAAA,CAAA,UAAG"}}, {"offset": {"line": 14, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/output/79fb1_turbopack-tests_tests_snapshot_imports_subpath-imports-nested_input_83c7e7._.js b/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/output/79fb1_turbopack-tests_tests_snapshot_imports_subpath-imports-nested_input_83c7e7._.js index a0ed6f986d896..b3249debfc235 100644 --- a/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/output/79fb1_turbopack-tests_tests_snapshot_imports_subpath-imports-nested_input_83c7e7._.js +++ b/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/output/79fb1_turbopack-tests_tests_snapshot_imports_subpath-imports-nested_input_83c7e7._.js @@ -1,6 +1,6 @@ (globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/79fb1_turbopack-tests_tests_snapshot_imports_subpath-imports-nested_input_83c7e7._.js", { -"[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/input/foo.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/input/foo.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; __turbopack_esm__({ @@ -9,7 +9,7 @@ __turbopack_esm__({ const __TURBOPACK__default__export__ = "foo"; })()), -"[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/input/nested/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/input/nested/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; __turbopack_esm__({ @@ -21,7 +21,7 @@ var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests const __TURBOPACK__default__export__ = __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$imports$2f$subpath$2d$imports$2d$nested$2f$input$2f$foo$2e$js__$5b$test$5d$__$28$ecmascript$29$__["default"]; })()), -"[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; __turbopack_esm__({}); diff --git a/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/output/79fb1_turbopack-tests_tests_snapshot_imports_subpath-imports-nested_input_83c7e7._.js.map b/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/output/79fb1_turbopack-tests_tests_snapshot_imports_subpath-imports-nested_input_83c7e7._.js.map index 858ec82049d52..f7a30062f0362 100644 --- a/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/output/79fb1_turbopack-tests_tests_snapshot_imports_subpath-imports-nested_input_83c7e7._.js.map +++ b/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/output/79fb1_turbopack-tests_tests_snapshot_imports_subpath-imports-nested_input_83c7e7._.js.map @@ -2,10 +2,10 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/input/foo.js"],"sourcesContent":["export default \"foo\";\n"],"names":[],"mappings":";;;uCAAe"}}, + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/input/foo.js"],"sourcesContent":["export default \"foo\";\n"],"names":[],"mappings":";;;uCAAe"}}, {"offset": {"line": 9, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 14, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/input/nested/index.js"],"sourcesContent":["import foo from \"#foo\";\nexport default foo;\n"],"names":[],"mappings":";;;;;;uCACe,sMAAA,CAAA,UAAG"}}, + {"offset": {"line": 14, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/input/nested/index.js"],"sourcesContent":["import foo from \"#foo\";\nexport default foo;\n"],"names":[],"mappings":";;;;;;uCACe,sMAAA,CAAA,UAAG"}}, {"offset": {"line": 21, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 26, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/input/index.js"],"sourcesContent":["import foo from \"./nested\";\n\nconsole.log(foo);\n"],"names":[],"mappings":";;;;AAEA,QAAQ,GAAG,CAAC,kNAAA,CAAA,UAAG"}}, + {"offset": {"line": 26, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/input/index.js"],"sourcesContent":["import foo from \"./nested\";\n\nconsole.log(foo);\n"],"names":[],"mappings":";;;;AAEA,QAAQ,GAAG,CAAC,kNAAA,CAAA,UAAG"}}, {"offset": {"line": 31, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/output/crates_turbopack-tests_tests_snapshot_imports_subpath-imports_input_f5873d._.js b/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/output/crates_turbopack-tests_tests_snapshot_imports_subpath-imports_input_f5873d._.js index 5543307a82be6..288e8056b1cfa 100644 --- a/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/output/crates_turbopack-tests_tests_snapshot_imports_subpath-imports_input_f5873d._.js +++ b/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/output/crates_turbopack-tests_tests_snapshot_imports_subpath-imports_input_f5873d._.js @@ -1,6 +1,6 @@ (globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_imports_subpath-imports_input_f5873d._.js", { -"[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/foo.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/foo.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; __turbopack_esm__({ @@ -9,7 +9,7 @@ __turbopack_esm__({ const __TURBOPACK__default__export__ = "foo"; })()), -"[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/dep/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/dep/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; __turbopack_esm__({ @@ -18,7 +18,7 @@ __turbopack_esm__({ const __TURBOPACK__default__export__ = "dep"; })()), -"[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/pat.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/pat.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; __turbopack_esm__({ @@ -27,7 +27,7 @@ __turbopack_esm__({ const __TURBOPACK__default__export__ = "pat"; })()), -"[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/import.mjs [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/import.mjs [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; __turbopack_esm__({ @@ -36,12 +36,12 @@ __turbopack_esm__({ const __TURBOPACK__default__export__ = "import"; })()), -"[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/require.cjs [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__, m: module, e: exports, t: require }) { !function() { +"[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/require.cjs [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { module.exports = "require"; }.call(this) }), -"[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; __turbopack_esm__({}); diff --git a/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/output/crates_turbopack-tests_tests_snapshot_imports_subpath-imports_input_f5873d._.js.map b/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/output/crates_turbopack-tests_tests_snapshot_imports_subpath-imports_input_f5873d._.js.map index 57dd03cce3073..ce53d823e7c64 100644 --- a/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/output/crates_turbopack-tests_tests_snapshot_imports_subpath-imports_input_f5873d._.js.map +++ b/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/output/crates_turbopack-tests_tests_snapshot_imports_subpath-imports_input_f5873d._.js.map @@ -2,16 +2,16 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/foo.js"],"sourcesContent":["export default \"foo\";\n"],"names":[],"mappings":";;;uCAAe"}}, + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/foo.js"],"sourcesContent":["export default \"foo\";\n"],"names":[],"mappings":";;;uCAAe"}}, {"offset": {"line": 9, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 14, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/dep/index.js"],"sourcesContent":["export default \"dep\";\n"],"names":[],"mappings":";;;uCAAe"}}, + {"offset": {"line": 14, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/dep/index.js"],"sourcesContent":["export default \"dep\";\n"],"names":[],"mappings":";;;uCAAe"}}, {"offset": {"line": 18, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 23, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/pat.js"],"sourcesContent":["export default \"pat\";\n"],"names":[],"mappings":";;;uCAAe"}}, + {"offset": {"line": 23, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/pat.js"],"sourcesContent":["export default \"pat\";\n"],"names":[],"mappings":";;;uCAAe"}}, {"offset": {"line": 27, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 32, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/import.mjs"],"sourcesContent":["export default \"import\";\n"],"names":[],"mappings":";;;uCAAe"}}, + {"offset": {"line": 32, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/import.mjs"],"sourcesContent":["export default \"import\";\n"],"names":[],"mappings":";;;uCAAe"}}, {"offset": {"line": 36, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 40, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/require.cjs"],"sourcesContent":["module.exports = \"require\";\n"],"names":[],"mappings":"AAAA,OAAO,OAAO,GAAG"}}, + {"offset": {"line": 40, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/require.cjs"],"sourcesContent":["module.exports = \"require\";\n"],"names":[],"mappings":"AAAA,OAAO,OAAO,GAAG"}}, {"offset": {"line": 41, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 46, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/index.js"],"sourcesContent":["import foo from \"#foo\";\nimport dep from \"#dep\";\nimport pattern from \"#pattern/pat.js\";\nimport conditionalImport from \"#conditional\";\nconst conditionalRequire = require(\"#conditional\");\n\nconsole.log(foo, dep, pattern, conditionalImport, conditionalRequire);\n"],"names":[],"mappings":";;;;;;;;;;AAIA,MAAM;AAEN,QAAQ,GAAG,CAAC,4LAAA,CAAA,UAAG,EAAE,qMAAA,CAAA,UAAG,EAAE,4LAAA,CAAA,UAAO,EAAE,gMAAA,CAAA,UAAiB,EAAE"}}, + {"offset": {"line": 46, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/index.js"],"sourcesContent":["import foo from \"#foo\";\nimport dep from \"#dep\";\nimport pattern from \"#pattern/pat.js\";\nimport conditionalImport from \"#conditional\";\nconst conditionalRequire = require(\"#conditional\");\n\nconsole.log(foo, dep, pattern, conditionalImport, conditionalRequire);\n"],"names":[],"mappings":";;;;;;;;;;AAIA,MAAM;AAEN,QAAQ,GAAG,CAAC,4LAAA,CAAA,UAAG,EAAE,qMAAA,CAAA,UAAG,EAAE,4LAAA,CAAA,UAAO,EAAE,gMAAA,CAAA,UAAiB,EAAE"}}, {"offset": {"line": 58, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/node/node_protocol_external/output/79fb1_turbopack-tests_tests_snapshot_node_node_protocol_external_input_index_8770aa.js b/crates/turbopack-tests/tests/snapshot/node/node_protocol_external/output/79fb1_turbopack-tests_tests_snapshot_node_node_protocol_external_input_index_8770aa.js index 57c6296d67338..bbae53d76a1f2 100644 --- a/crates/turbopack-tests/tests/snapshot/node/node_protocol_external/output/79fb1_turbopack-tests_tests_snapshot_node_node_protocol_external_input_index_8770aa.js +++ b/crates/turbopack-tests/tests/snapshot/node/node_protocol_external/output/79fb1_turbopack-tests_tests_snapshot_node_node_protocol_external_input_index_8770aa.js @@ -1,6 +1,6 @@ (globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/79fb1_turbopack-tests_tests_snapshot_node_node_protocol_external_input_index_8770aa.js", { -"[project]/crates/turbopack-tests/tests/snapshot/node/node_protocol_external/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, x: __turbopack_external_require__, y: __turbopack_external_import__, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/node/node_protocol_external/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, x: __turbopack_external_require__, y: __turbopack_external_import__ }) => (() => { "use strict"; __turbopack_esm__({}); diff --git a/crates/turbopack-tests/tests/snapshot/node/spawn_dynamic/output/crates_turbopack-tests_tests_snapshot_node_spawn_dynamic_input_e65664._.js b/crates/turbopack-tests/tests/snapshot/node/spawn_dynamic/output/crates_turbopack-tests_tests_snapshot_node_spawn_dynamic_input_e65664._.js index ecbe252ddbecd..1e8e487649901 100644 --- a/crates/turbopack-tests/tests/snapshot/node/spawn_dynamic/output/crates_turbopack-tests_tests_snapshot_node_spawn_dynamic_input_e65664._.js +++ b/crates/turbopack-tests/tests/snapshot/node/spawn_dynamic/output/crates_turbopack-tests_tests_snapshot_node_spawn_dynamic_input_e65664._.js @@ -1,6 +1,6 @@ (globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_node_spawn_dynamic_input_e65664._.js", { -"[project]/crates/turbopack-tests/tests/snapshot/node/spawn_dynamic/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, x: __turbopack_external_require__, y: __turbopack_external_import__, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/node/spawn_dynamic/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, x: __turbopack_external_require__, y: __turbopack_external_import__ }) => (() => { "use strict"; __turbopack_esm__({}); @@ -15,7 +15,7 @@ const proc = (0, __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbo ]); })()), -"[project]/crates/turbopack-tests/tests/snapshot/node/spawn_dynamic/input/node_modules/child_process/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, x: __turbopack_external_require__, y: __turbopack_external_import__, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/node/spawn_dynamic/input/node_modules/child_process/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, x: __turbopack_external_require__, y: __turbopack_external_import__ }) => (() => { "use strict"; __turbopack_esm__({ diff --git a/crates/turbopack-tests/tests/snapshot/node/spawn_dynamic/output/crates_turbopack-tests_tests_snapshot_node_spawn_dynamic_input_e65664._.js.map b/crates/turbopack-tests/tests/snapshot/node/spawn_dynamic/output/crates_turbopack-tests_tests_snapshot_node_spawn_dynamic_input_e65664._.js.map index ee19bded147c4..2cf2e680f6035 100644 --- a/crates/turbopack-tests/tests/snapshot/node/spawn_dynamic/output/crates_turbopack-tests_tests_snapshot_node_spawn_dynamic_input_e65664._.js.map +++ b/crates/turbopack-tests/tests/snapshot/node/spawn_dynamic/output/crates_turbopack-tests_tests_snapshot_node_spawn_dynamic_input_e65664._.js.map @@ -2,8 +2,8 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/node/spawn_dynamic/input/index.js"],"sourcesContent":["import { spawn } from \"child_process\";\n\nconst program = ['ls'];\nconst proc = spawn(program[0], ['-la']);\n"],"names":[],"mappings":";;;;AAEA,MAAM,UAAU;IAAC;CAAK;AACtB,MAAM,OAAO,CAAA,GAAA,uNAAA,CAAA,QAAK,AAAD,EAAE,OAAO,CAAC,EAAE,EAAE;IAAC;CAAM"}}, + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/node/spawn_dynamic/input/index.js"],"sourcesContent":["import { spawn } from \"child_process\";\n\nconst program = ['ls'];\nconst proc = spawn(program[0], ['-la']);\n"],"names":[],"mappings":";;;;AAEA,MAAM,UAAU;IAAC;CAAK;AACtB,MAAM,OAAO,CAAA,GAAA,uNAAA,CAAA,QAAK,AAAD,EAAE,OAAO,CAAC,EAAE,EAAE;IAAC;CAAM"}}, {"offset": {"line": 15, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 20, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/node/spawn_dynamic/input/node_modules/child_process/index.js"],"sourcesContent":["export function spawn(cmd, args) {\n //\n}\n"],"names":[],"mappings":";;;AAAO,SAAS,MAAM,GAAG,EAAE,IAAI;AAC7B,EAAE;AACJ"}}, + {"offset": {"line": 20, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/node/spawn_dynamic/input/node_modules/child_process/index.js"],"sourcesContent":["export function spawn(cmd, args) {\n //\n}\n"],"names":[],"mappings":";;;AAAO,SAAS,MAAM,GAAG,EAAE,IAAI;AAC7B,EAAE;AACJ"}}, {"offset": {"line": 26, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/node/spawn_node_eval/output/crates_turbopack-tests_tests_snapshot_node_spawn_node_eval_input_d0030e._.js b/crates/turbopack-tests/tests/snapshot/node/spawn_node_eval/output/crates_turbopack-tests_tests_snapshot_node_spawn_node_eval_input_d0030e._.js index be35fd31015e2..b7908aae10751 100644 --- a/crates/turbopack-tests/tests/snapshot/node/spawn_node_eval/output/crates_turbopack-tests_tests_snapshot_node_spawn_node_eval_input_d0030e._.js +++ b/crates/turbopack-tests/tests/snapshot/node/spawn_node_eval/output/crates_turbopack-tests_tests_snapshot_node_spawn_node_eval_input_d0030e._.js @@ -1,6 +1,6 @@ (globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_node_spawn_node_eval_input_d0030e._.js", { -"[project]/crates/turbopack-tests/tests/snapshot/node/spawn_node_eval/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, x: __turbopack_external_require__, y: __turbopack_external_import__, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/node/spawn_node_eval/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, x: __turbopack_external_require__, y: __turbopack_external_import__ }) => (() => { "use strict"; __turbopack_esm__({}); @@ -13,7 +13,7 @@ let x = (0, __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$ ]); })()), -"[project]/crates/turbopack-tests/tests/snapshot/node/spawn_node_eval/input/node_modules/child_process/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, x: __turbopack_external_require__, y: __turbopack_external_import__, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/node/spawn_node_eval/input/node_modules/child_process/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, x: __turbopack_external_require__, y: __turbopack_external_import__ }) => (() => { "use strict"; __turbopack_esm__({ diff --git a/crates/turbopack-tests/tests/snapshot/node/spawn_node_eval/output/crates_turbopack-tests_tests_snapshot_node_spawn_node_eval_input_d0030e._.js.map b/crates/turbopack-tests/tests/snapshot/node/spawn_node_eval/output/crates_turbopack-tests_tests_snapshot_node_spawn_node_eval_input_d0030e._.js.map index 0a46452b7d9f4..473760c1138a0 100644 --- a/crates/turbopack-tests/tests/snapshot/node/spawn_node_eval/output/crates_turbopack-tests_tests_snapshot_node_spawn_node_eval_input_d0030e._.js.map +++ b/crates/turbopack-tests/tests/snapshot/node/spawn_node_eval/output/crates_turbopack-tests_tests_snapshot_node_spawn_node_eval_input_d0030e._.js.map @@ -2,8 +2,8 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/node/spawn_node_eval/input/index.js"],"sourcesContent":["import { spawn } from \"child_process\";\n\nlet x = spawn(process.argv[0], [\"-e\", \"console.log('foo');\"]);\n"],"names":[],"mappings":";;;;AAEA,IAAI,IAAI,CAAA,GAAA,yNAAA,CAAA,QAAK,AAAD,EAAE,QAAQ,IAAI,CAAC,EAAE,EAAE;IAAC;IAAM;CAAsB"}}, + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/node/spawn_node_eval/input/index.js"],"sourcesContent":["import { spawn } from \"child_process\";\n\nlet x = spawn(process.argv[0], [\"-e\", \"console.log('foo');\"]);\n"],"names":[],"mappings":";;;;AAEA,IAAI,IAAI,CAAA,GAAA,yNAAA,CAAA,QAAK,AAAD,EAAE,QAAQ,IAAI,CAAC,EAAE,EAAE;IAAC;IAAM;CAAsB"}}, {"offset": {"line": 13, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 18, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/node/spawn_node_eval/input/node_modules/child_process/index.js"],"sourcesContent":["export function spawn(cmd, args) {\n //\n}\n"],"names":[],"mappings":";;;AAAO,SAAS,MAAM,GAAG,EAAE,IAAI;AAC7B,EAAE;AACJ"}}, + {"offset": {"line": 18, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/node/spawn_node_eval/input/node_modules/child_process/index.js"],"sourcesContent":["export function spawn(cmd, args) {\n //\n}\n"],"names":[],"mappings":";;;AAAO,SAAS,MAAM,GAAG,EAAE,IAAI;AAC7B,EAAE;AACJ"}}, {"offset": {"line": 24, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/runtime/default_build_runtime/output/79fb1_turbopack-tests_tests_snapshot_runtime_default_build_runtime_input_index_e22b2e.js.map b/crates/turbopack-tests/tests/snapshot/runtime/default_build_runtime/output/79fb1_turbopack-tests_tests_snapshot_runtime_default_build_runtime_input_index_e22b2e.js.map index 02d3d020701ae..b712177004c01 100644 --- a/crates/turbopack-tests/tests/snapshot/runtime/default_build_runtime/output/79fb1_turbopack-tests_tests_snapshot_runtime_default_build_runtime_input_index_e22b2e.js.map +++ b/crates/turbopack-tests/tests/snapshot/runtime/default_build_runtime/output/79fb1_turbopack-tests_tests_snapshot_runtime_default_build_runtime_input_index_e22b2e.js.map @@ -2,6 +2,6 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/runtime/default_build_runtime/input/index.js"],"sourcesContent":["console.log(\"Hello, world!\");\n"],"names":[],"mappings":"AAAA,QAAQ,GAAG,CAAC"}}, + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/runtime/default_build_runtime/input/index.js"],"sourcesContent":["console.log(\"Hello, world!\");\n"],"names":[],"mappings":"AAAA,QAAQ,GAAG,CAAC"}}, {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/runtime/default_build_runtime/output/[turbopack]_runtime.js.map b/crates/turbopack-tests/tests/snapshot/runtime/default_build_runtime/output/[turbopack]_runtime.js.map index d5ef8f5ccdda5..d90f62c71f49a 100644 --- a/crates/turbopack-tests/tests/snapshot/runtime/default_build_runtime/output/[turbopack]_runtime.js.map +++ b/crates/turbopack-tests/tests/snapshot/runtime/default_build_runtime/output/[turbopack]_runtime.js.map @@ -2,9 +2,9 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 3, "column": 0}, "map": {"version":3,"sources":["/turbopack/[turbopack]/shared/runtime-utils.ts"],"sourcesContent":["/**\n * This file contains runtime types and functions that are shared between all\n * TurboPack ECMAScript runtimes.\n *\n * It will be prepended to the runtime code of each runtime.\n */\n\n/* eslint-disable @next/next/no-assign-module-variable */\n\n/// \n\ninterface Exports {\n __esModule?: boolean;\n\n [key: string]: any;\n}\n\ntype EsmNamespaceObject = Record;\n\nconst REEXPORTED_OBJECTS = Symbol(\"reexported objects\");\n\ninterface BaseModule {\n exports: Function | Exports | Promise | AsyncModulePromise;\n error: Error | undefined;\n loaded: boolean;\n id: ModuleId;\n children: ModuleId[];\n parents: ModuleId[];\n namespaceObject?:\n | EsmNamespaceObject\n | Promise\n | AsyncModulePromise;\n [REEXPORTED_OBJECTS]?: any[];\n}\n\ninterface Module extends BaseModule {}\n\ntype ModuleContextMap = Record;\n\ninterface ModuleContextEntry {\n id: () => ModuleId;\n module: () => any;\n}\n\ninterface ModuleContext {\n // require call\n (moduleId: ModuleId): Exports | EsmNamespaceObject;\n\n // async import call\n import(moduleId: ModuleId): Promise;\n\n keys(): ModuleId[];\n\n resolve(moduleId: ModuleId): ModuleId;\n}\n\ntype GetOrInstantiateModuleFromParent = (\n moduleId: ModuleId,\n parentModule: Module\n) => Module;\n\nconst hasOwnProperty = Object.prototype.hasOwnProperty;\nconst toStringTag = typeof Symbol !== \"undefined\" && Symbol.toStringTag;\n\nfunction defineProp(\n obj: any,\n name: PropertyKey,\n options: PropertyDescriptor & ThisType\n) {\n if (!hasOwnProperty.call(obj, name))\n Object.defineProperty(obj, name, options);\n}\n\n/**\n * Adds the getters to the exports object.\n */\nfunction esm(exports: Exports, getters: Record any>) {\n defineProp(exports, \"__esModule\", { value: true });\n if (toStringTag) defineProp(exports, toStringTag, { value: \"Module\" });\n for (const key in getters) {\n defineProp(exports, key, { get: getters[key], enumerable: true });\n }\n}\n\n/**\n * Makes the module an ESM with exports\n */\nfunction esmExport(\n module: Module,\n exports: Exports,\n getters: Record any>\n) {\n module.namespaceObject = module.exports;\n esm(exports, getters);\n}\n\nfunction ensureDynamicExports(module: Module, exports: Exports) {\n let reexportedObjects = module[REEXPORTED_OBJECTS];\n\n if (!reexportedObjects) {\n reexportedObjects = module[REEXPORTED_OBJECTS] = [];\n module.exports = module.namespaceObject = new Proxy(exports, {\n get(target, prop) {\n if (\n hasOwnProperty.call(target, prop) ||\n prop === \"default\" ||\n prop === \"__esModule\"\n ) {\n return Reflect.get(target, prop);\n }\n for (const obj of reexportedObjects!) {\n const value = Reflect.get(obj, prop);\n if (value !== undefined) return value;\n }\n return undefined;\n },\n ownKeys(target) {\n const keys = Reflect.ownKeys(target);\n for (const obj of reexportedObjects!) {\n for (const key of Reflect.ownKeys(obj)) {\n if (key !== \"default\" && !keys.includes(key)) keys.push(key);\n }\n }\n return keys;\n },\n });\n }\n}\n\n/**\n * Dynamically exports properties from an object\n */\nfunction dynamicExport(\n module: Module,\n exports: Exports,\n object: Record\n) {\n ensureDynamicExports(module, exports);\n\n if (typeof object === \"object\" && object !== null) {\n module[REEXPORTED_OBJECTS]!.push(object);\n }\n}\n\nfunction exportValue(module: Module, value: any) {\n module.exports = value;\n}\n\nfunction exportNamespace(module: Module, namespace: any) {\n module.exports = module.namespaceObject = namespace;\n}\n\nfunction createGetter(obj: Record, key: string | symbol) {\n return () => obj[key];\n}\n\n/**\n * @returns prototype of the object\n */\nconst getProto: (obj: any) => any = Object.getPrototypeOf\n ? (obj) => Object.getPrototypeOf(obj)\n : (obj) => obj.__proto__;\n\n/** Prototypes that are not expanded for exports */\nconst LEAF_PROTOTYPES = [null, getProto({}), getProto([]), getProto(getProto)];\n\n/**\n * @param raw\n * @param ns\n * @param allowExportDefault\n * * `false`: will have the raw module as default export\n * * `true`: will have the default property as default export\n */\nfunction interopEsm(\n raw: Exports,\n ns: EsmNamespaceObject,\n allowExportDefault?: boolean\n) {\n const getters: { [s: string]: () => any } = Object.create(null);\n for (\n let current = raw;\n (typeof current === \"object\" || typeof current === \"function\") &&\n !LEAF_PROTOTYPES.includes(current);\n current = getProto(current)\n ) {\n for (const key of Object.getOwnPropertyNames(current)) {\n getters[key] = createGetter(raw, key);\n }\n }\n\n // this is not really correct\n // we should set the `default` getter if the imported module is a `.cjs file`\n if (!(allowExportDefault && \"default\" in getters)) {\n getters[\"default\"] = () => raw;\n }\n\n esm(ns, getters);\n return ns;\n}\n\nfunction createNS(raw: BaseModule[\"exports\"]): EsmNamespaceObject {\n if (typeof raw === \"function\") {\n return function (this: any, ...args: any[]) {\n return raw.apply(this, args);\n };\n } else {\n return Object.create(null);\n }\n}\n\nfunction esmImport(\n sourceModule: Module,\n id: ModuleId\n): Exclude {\n const module = getOrInstantiateModuleFromParent(id, sourceModule);\n if (module.error) throw module.error;\n\n // any ES module has to have `module.namespaceObject` defined.\n if (module.namespaceObject) return module.namespaceObject;\n\n // only ESM can be an async module, so we don't need to worry about exports being a promise here.\n const raw = module.exports;\n return (module.namespaceObject = interopEsm(\n raw,\n createNS(raw),\n raw && (raw as any).__esModule\n ));\n}\n\n// Add a simple runtime require so that environments without one can still pass\n// `typeof require` CommonJS checks so that exports are correctly registered.\nconst runtimeRequire =\n typeof require === \"function\"\n ? require\n : function require() {\n throw new Error(\"Unexpected use of runtime require\");\n };\n\nfunction commonJsRequire(sourceModule: Module, id: ModuleId): Exports {\n const module = getOrInstantiateModuleFromParent(id, sourceModule);\n if (module.error) throw module.error;\n return module.exports;\n}\n\n/**\n * `require.context` and require/import expression runtime.\n */\nfunction moduleContext(map: ModuleContextMap): ModuleContext {\n function moduleContext(id: ModuleId): Exports {\n if (hasOwnProperty.call(map, id)) {\n return map[id].module();\n }\n\n const e = new Error(`Cannot find module '${name}'`);\n (e as any).code = \"MODULE_NOT_FOUND\";\n throw e;\n }\n\n moduleContext.keys = (): ModuleId[] => {\n return Object.keys(map);\n };\n\n moduleContext.resolve = (id: ModuleId): ModuleId => {\n if (hasOwnProperty.call(map, id)) {\n return map[id].id();\n }\n\n const e = new Error(`Cannot find module '${name}'`);\n (e as any).code = \"MODULE_NOT_FOUND\";\n throw e;\n };\n\n moduleContext.import = async (id: ModuleId) => {\n return await (moduleContext(id) as Promise);\n };\n\n return moduleContext;\n}\n\n/**\n * Returns the path of a chunk defined by its data.\n */\nfunction getChunkPath(chunkData: ChunkData): ChunkPath {\n return typeof chunkData === \"string\" ? chunkData : chunkData.path;\n}\n\nfunction isPromise(maybePromise: any): maybePromise is Promise {\n return (\n maybePromise != null &&\n typeof maybePromise === \"object\" &&\n \"then\" in maybePromise &&\n typeof maybePromise.then === \"function\"\n );\n}\n\nfunction isAsyncModuleExt(obj: T): obj is AsyncModuleExt & T {\n return turbopackQueues in obj;\n}\n\nfunction createPromise() {\n let resolve: (value: T | PromiseLike) => void;\n let reject: (reason?: any) => void;\n\n const promise = new Promise((res, rej) => {\n reject = rej;\n resolve = res;\n });\n\n return {\n promise,\n resolve: resolve!,\n reject: reject!,\n };\n}\n\n// everything below is adapted from webpack\n// https://github.com/webpack/webpack/blob/6be4065ade1e252c1d8dcba4af0f43e32af1bdc1/lib/runtime/AsyncModuleRuntimeModule.js#L13\n\nconst turbopackQueues = Symbol(\"turbopack queues\");\nconst turbopackExports = Symbol(\"turbopack exports\");\nconst turbopackError = Symbol(\"turbopack error\");\n\ntype AsyncQueueFn = (() => void) & { queueCount: number };\ntype AsyncQueue = AsyncQueueFn[] & { resolved: boolean };\n\nfunction resolveQueue(queue?: AsyncQueue) {\n if (queue && !queue.resolved) {\n queue.resolved = true;\n queue.forEach((fn) => fn.queueCount--);\n queue.forEach((fn) => (fn.queueCount-- ? fn.queueCount++ : fn()));\n }\n}\n\ntype Dep = Exports | AsyncModulePromise | Promise;\n\ntype AsyncModuleExt = {\n [turbopackQueues]: (fn: (queue: AsyncQueue) => void) => void;\n [turbopackExports]: Exports;\n [turbopackError]?: any;\n};\n\ntype AsyncModulePromise = Promise & AsyncModuleExt;\n\nfunction wrapDeps(deps: Dep[]): AsyncModuleExt[] {\n return deps.map((dep) => {\n if (dep !== null && typeof dep === \"object\") {\n if (isAsyncModuleExt(dep)) return dep;\n if (isPromise(dep)) {\n const queue: AsyncQueue = Object.assign([], { resolved: false });\n\n const obj: AsyncModuleExt = {\n [turbopackExports]: {},\n [turbopackQueues]: (fn: (queue: AsyncQueue) => void) => fn(queue),\n };\n\n dep.then(\n (res) => {\n obj[turbopackExports] = res;\n resolveQueue(queue);\n },\n (err) => {\n obj[turbopackError] = err;\n resolveQueue(queue);\n }\n );\n\n return obj;\n }\n }\n\n const ret: AsyncModuleExt = {\n [turbopackExports]: dep,\n [turbopackQueues]: () => {},\n };\n\n return ret;\n });\n}\n\nfunction asyncModule(\n module: Module,\n body: (\n handleAsyncDependencies: (\n deps: Dep[]\n ) => Exports[] | Promise<() => Exports[]>,\n asyncResult: (err?: any) => void\n ) => void,\n hasAwait: boolean\n) {\n const queue: AsyncQueue | undefined = hasAwait\n ? Object.assign([], { resolved: true })\n : undefined;\n\n const depQueues: Set = new Set();\n\n ensureDynamicExports(module, module.exports);\n const exports = module.exports;\n\n const { resolve, reject, promise: rawPromise } = createPromise();\n\n const promise: AsyncModulePromise = Object.assign(rawPromise, {\n [turbopackExports]: exports,\n [turbopackQueues]: (fn) => {\n queue && fn(queue);\n depQueues.forEach(fn);\n promise[\"catch\"](() => {});\n },\n } satisfies AsyncModuleExt);\n\n module.exports = module.namespaceObject = promise;\n\n function handleAsyncDependencies(deps: Dep[]) {\n const currentDeps = wrapDeps(deps);\n\n const getResult = () =>\n currentDeps.map((d) => {\n if (d[turbopackError]) throw d[turbopackError];\n return d[turbopackExports];\n });\n\n const { promise, resolve } = createPromise<() => Exports[]>();\n\n const fn: AsyncQueueFn = Object.assign(() => resolve(getResult), {\n queueCount: 0,\n });\n\n function fnQueue(q: AsyncQueue) {\n if (q !== queue && !depQueues.has(q)) {\n depQueues.add(q);\n if (q && !q.resolved) {\n fn.queueCount++;\n q.push(fn);\n }\n }\n }\n\n currentDeps.map((dep) => dep[turbopackQueues](fnQueue));\n\n return fn.queueCount ? promise : getResult();\n }\n\n function asyncResult(err?: any) {\n if (err) {\n reject((promise[turbopackError] = err));\n } else {\n resolve(exports);\n }\n\n resolveQueue(queue);\n }\n\n body(handleAsyncDependencies, asyncResult);\n\n if (queue) {\n queue.resolved = false;\n }\n}\n\n/**\n * A pseudo \"fake\" URL object to resolve to its relative path.\n *\n * When UrlRewriteBehavior is set to relative, calls to the `new URL()` will construct url without base using this\n * runtime function to generate context-agnostic urls between different rendering context, i.e ssr / client to avoid\n * hydration mismatch.\n *\n * This is based on webpack's existing implementation:\n * https://github.com/webpack/webpack/blob/87660921808566ef3b8796f8df61bd79fc026108/lib/runtime/RelativeUrlRuntimeModule.js\n */\nconst relativeURL = function relativeURL(this: any, inputUrl: string) {\n const realUrl = new URL(inputUrl, \"x:/\");\n const values: Record = {};\n for (const key in realUrl) values[key] = (realUrl as any)[key];\n values.href = inputUrl;\n values.pathname = inputUrl.replace(/[?#].*/, \"\");\n values.origin = values.protocol = \"\";\n values.toString = values.toJSON = (..._args: Array) => inputUrl;\n for (const key in values)\n Object.defineProperty(this, key, {\n enumerable: true,\n configurable: true,\n value: values[key],\n });\n};\n\nrelativeURL.prototype = URL.prototype;\n"],"names":[],"mappings":"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"}}, - {"offset": {"line": 307, "column": 0}, "map": {"version":3,"sources":["/turbopack/[turbopack]/shared-node/base-externals-utils.ts"],"sourcesContent":["/// \n\n/// A 'base' utilities to support runtime can have externals.\n/// Currently this is for node.js / edge runtime both.\n/// If a fn requires node.js specific behavior, it should be placed in `node-external-utils` instead.\n\nasync function externalImport(id: ModuleId) {\n let raw;\n try {\n raw = await import(id);\n } catch (err) {\n // TODO(alexkirsz) This can happen when a client-side module tries to load\n // an external module we don't provide a shim for (e.g. querystring, url).\n // For now, we fail semi-silently, but in the future this should be a\n // compilation error.\n throw new Error(`Failed to load external module ${id}: ${err}`);\n }\n\n if (raw && raw.__esModule && raw.default && \"default\" in raw.default) {\n return interopEsm(raw.default, createNS(raw), true);\n }\n\n return raw;\n}\n\nfunction externalRequire(\n id: ModuleId,\n esm: boolean = false\n): Exports | EsmNamespaceObject {\n let raw;\n try {\n raw = require(id);\n } catch (err) {\n // TODO(alexkirsz) This can happen when a client-side module tries to load\n // an external module we don't provide a shim for (e.g. querystring, url).\n // For now, we fail semi-silently, but in the future this should be a\n // compilation error.\n throw new Error(`Failed to load external module ${id}: ${err}`);\n }\n\n if (!esm || raw.__esModule) {\n return raw;\n }\n\n return interopEsm(raw, createNS(raw), true);\n}\n\nexternalRequire.resolve = (\n id: string,\n options?: {\n paths?: string[];\n }\n) => {\n return require.resolve(id, options);\n};\n"],"names":[],"mappings":"AAAA,mDAAmD;AAEnD,6DAA6D;AAC7D,sDAAsD;AACtD,qGAAqG;AAErG,eAAe,eAAe,EAAY;IACxC,IAAI;IACJ,IAAI;QACF,MAAM,MAAM,MAAM,CAAC;IACrB,EAAE,OAAO,KAAK;QACZ,0EAA0E;QAC1E,0EAA0E;QAC1E,qEAAqE;QACrE,qBAAqB;QACrB,MAAM,IAAI,MAAM,CAAC,+BAA+B,EAAE,GAAG,EAAE,EAAE,IAAI,CAAC;IAChE;IAEA,IAAI,OAAO,IAAI,UAAU,IAAI,IAAI,OAAO,IAAI,aAAa,IAAI,OAAO,EAAE;QACpE,OAAO,WAAW,IAAI,OAAO,EAAE,SAAS,MAAM;IAChD;IAEA,OAAO;AACT;AAEA,SAAS,gBACP,EAAY,EACZ,MAAe,KAAK;IAEpB,IAAI;IACJ,IAAI;QACF,MAAM,QAAQ;IAChB,EAAE,OAAO,KAAK;QACZ,0EAA0E;QAC1E,0EAA0E;QAC1E,qEAAqE;QACrE,qBAAqB;QACrB,MAAM,IAAI,MAAM,CAAC,+BAA+B,EAAE,GAAG,EAAE,EAAE,IAAI,CAAC;IAChE;IAEA,IAAI,CAAC,OAAO,IAAI,UAAU,EAAE;QAC1B,OAAO;IACT;IAEA,OAAO,WAAW,KAAK,SAAS,MAAM;AACxC;AAEA,gBAAgB,OAAO,GAAG,CACxB,IACA;IAIA,OAAO,QAAQ,OAAO,CAAC,IAAI;AAC7B"}}, - {"offset": {"line": 346, "column": 0}, "map": {"version":3,"sources":["/turbopack/[turbopack]/shared-node/node-externals-utils.ts"],"sourcesContent":["declare var RUNTIME_PUBLIC_PATH: string;\ndeclare var OUTPUT_ROOT: string;\ndeclare var ASSET_PREFIX: string;\n\nconst path = require(\"path\");\n\nconst relativePathToRuntimeRoot = path.relative(RUNTIME_PUBLIC_PATH, \".\");\n// Compute the relative path to the `distDir`.\nconst relativePathToDistRoot = path.relative(\n path.join(OUTPUT_ROOT, RUNTIME_PUBLIC_PATH),\n \".\"\n);\nconst RUNTIME_ROOT = path.resolve(__filename, relativePathToRuntimeRoot);\n// Compute the absolute path to the root, by stripping distDir from the absolute path to this file.\nconst ABSOLUTE_ROOT = path.resolve(__filename, relativePathToDistRoot);\n\n/**\n * Returns an absolute path to the given module path.\n * Module path should be relative, either path to a file or a directory.\n *\n * This fn allows to calculate an absolute path for some global static values, such as\n * `__dirname` or `import.meta.url` that Turbopack will not embeds in compile time.\n * See ImportMetaBinding::code_generation for the usage.\n */\nfunction resolveAbsolutePath(modulePath?: string): string {\n if (modulePath) {\n return path.join(ABSOLUTE_ROOT, modulePath);\n }\n return ABSOLUTE_ROOT;\n}\n"],"names":[],"mappings":"AAIA,MAAM,OAAO,QAAQ;AAErB,MAAM,4BAA4B,KAAK,QAAQ,CAAC,qBAAqB;AACrE,8CAA8C;AAC9C,MAAM,yBAAyB,KAAK,QAAQ,CAC1C,KAAK,IAAI,CAAC,aAAa,sBACvB;AAEF,MAAM,eAAe,KAAK,OAAO,CAAC,YAAY;AAC9C,mGAAmG;AACnG,MAAM,gBAAgB,KAAK,OAAO,CAAC,YAAY;AAE/C;;;;;;;CAOC,GACD,SAAS,oBAAoB,UAAmB;IAC9C,IAAI,YAAY;QACd,OAAO,KAAK,IAAI,CAAC,eAAe;IAClC;IACA,OAAO;AACT"}}, - {"offset": {"line": 366, "column": 0}, "map": {"version":3,"sources":["/turbopack/[turbopack]/shared-node/node-wasm-utils.ts"],"sourcesContent":["/// \n\nfunction readWebAssemblyAsResponse(path: string) {\n const { createReadStream } = require(\"fs\") as typeof import(\"fs\");\n const { Readable } = require(\"stream\") as typeof import(\"stream\");\n\n const stream = createReadStream(path);\n\n // @ts-ignore unfortunately there's a slight type mismatch with the stream.\n return new Response(Readable.toWeb(stream), {\n headers: {\n \"content-type\": \"application/wasm\",\n },\n });\n}\n\nasync function compileWebAssemblyFromPath(\n path: string\n): Promise {\n const response = readWebAssemblyAsResponse(path);\n\n return await WebAssembly.compileStreaming(response);\n}\n\nasync function instantiateWebAssemblyFromPath(\n path: string,\n importsObj: WebAssembly.Imports\n): Promise {\n const response = readWebAssemblyAsResponse(path);\n\n const { instance } = await WebAssembly.instantiateStreaming(\n response,\n importsObj\n );\n\n return instance.exports;\n}\n"],"names":[],"mappings":"AAAA,mDAAmD;AAEnD,SAAS,0BAA0B,IAAY;IAC7C,MAAM,EAAE,gBAAgB,EAAE,GAAG,QAAQ;IACrC,MAAM,EAAE,QAAQ,EAAE,GAAG,QAAQ;IAE7B,MAAM,SAAS,iBAAiB;IAEhC,2EAA2E;IAC3E,OAAO,IAAI,SAAS,SAAS,KAAK,CAAC,SAAS;QAC1C,SAAS;YACP,gBAAgB;QAClB;IACF;AACF;AAEA,eAAe,2BACb,IAAY;IAEZ,MAAM,WAAW,0BAA0B;IAE3C,OAAO,MAAM,YAAY,gBAAgB,CAAC;AAC5C;AAEA,eAAe,+BACb,IAAY,EACZ,UAA+B;IAE/B,MAAM,WAAW,0BAA0B;IAE3C,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,YAAY,oBAAoB,CACzD,UACA;IAGF,OAAO,SAAS,OAAO;AACzB"}}, - {"offset": {"line": 387, "column": 0}, "map": {"version":3,"sources":["/turbopack/[turbopack]/build/runtime.ts"],"sourcesContent":["/// \n/// \n/// \n/// \n\nenum SourceType {\n /**\n * The module was instantiated because it was included in an evaluated chunk's\n * runtime.\n */\n Runtime = 0,\n /**\n * The module was instantiated because a parent module imported it.\n */\n Parent = 1,\n}\n\ntype SourceInfo =\n | {\n type: SourceType.Runtime;\n chunkPath: ChunkPath;\n }\n | {\n type: SourceType.Parent;\n parentId: ModuleId;\n };\n\nfunction stringifySourceInfo(source: SourceInfo): string {\n switch (source.type) {\n case SourceType.Runtime:\n return `runtime for chunk ${source.chunkPath}`;\n case SourceType.Parent:\n return `parent module ${source.parentId}`;\n }\n}\n\ntype ExternalRequire = (id: ModuleId) => Exports | EsmNamespaceObject;\ntype ExternalImport = (id: ModuleId) => Promise;\ntype ResolveAbsolutePath = (modulePath?: string) => string;\n\ninterface TurbopackNodeBuildContext extends TurbopackBaseContext {\n P: ResolveAbsolutePath;\n R: ResolvePathFromModule;\n x: ExternalRequire;\n y: ExternalImport;\n}\n\ntype ModuleFactory = (\n this: Module[\"exports\"],\n context: TurbopackNodeBuildContext\n) => undefined;\n\nconst url = require(\"url\");\n\nconst moduleFactories: ModuleFactories = Object.create(null);\nconst moduleCache: ModuleCache = Object.create(null);\n\n/**\n * Returns an absolute path to the given module's id.\n */\nfunction createResolvePathFromModule(\n resolver: (moduleId: string) => Exports\n): (moduleId: string) => string {\n return function resolvePathFromModule(moduleId: string): string {\n const exported = resolver(moduleId);\n const exportedPath = exported?.default ?? exported;\n if (typeof exportedPath !== \"string\") {\n return exported as any;\n }\n\n const strippedAssetPrefix = exportedPath.slice(ASSET_PREFIX.length);\n const resolved = path.resolve(\n ABSOLUTE_ROOT,\n OUTPUT_ROOT,\n strippedAssetPrefix\n );\n\n return url.pathToFileURL(resolved);\n };\n}\n\nfunction loadChunk(chunkData: ChunkData, source?: SourceInfo): void {\n if (typeof chunkData === \"string\") {\n return loadChunkPath(chunkData, source);\n } else {\n return loadChunkPath(chunkData.path, source);\n }\n}\n\nfunction loadChunkPath(chunkPath: ChunkPath, source?: SourceInfo): void {\n if (!chunkPath.endsWith(\".js\")) {\n // We only support loading JS chunks in Node.js.\n // This branch can be hit when trying to load a CSS chunk.\n return;\n }\n\n try {\n const resolved = path.resolve(RUNTIME_ROOT, chunkPath);\n const chunkModules: ModuleFactories = require(resolved);\n\n for (const [moduleId, moduleFactory] of Object.entries(chunkModules)) {\n if (!moduleFactories[moduleId]) {\n moduleFactories[moduleId] = moduleFactory;\n }\n }\n } catch (e) {\n let errorMessage = `Failed to load chunk ${chunkPath}`;\n\n if (source) {\n errorMessage += ` from ${stringifySourceInfo(source)}`;\n }\n\n throw new Error(errorMessage, {\n cause: e,\n });\n }\n}\n\nasync function loadChunkAsync(\n source: SourceInfo,\n chunkData: ChunkData\n): Promise {\n return new Promise((resolve, reject) => {\n try {\n loadChunk(chunkData, source);\n } catch (err) {\n reject(err);\n return;\n }\n resolve();\n });\n}\n\nfunction loadWebAssembly(chunkPath: ChunkPath, imports: WebAssembly.Imports) {\n const resolved = path.resolve(RUNTIME_ROOT, chunkPath);\n\n return instantiateWebAssemblyFromPath(resolved, imports);\n}\n\nfunction loadWebAssemblyModule(chunkPath: ChunkPath) {\n const resolved = path.resolve(RUNTIME_ROOT, chunkPath);\n\n return compileWebAssemblyFromPath(resolved);\n}\n\nfunction instantiateModule(id: ModuleId, source: SourceInfo): Module {\n const moduleFactory = moduleFactories[id];\n if (typeof moduleFactory !== \"function\") {\n // This can happen if modules incorrectly handle HMR disposes/updates,\n // e.g. when they keep a `setTimeout` around which still executes old code\n // and contains e.g. a `require(\"something\")` call.\n let instantiationReason;\n switch (source.type) {\n case SourceType.Runtime:\n instantiationReason = `as a runtime entry of chunk ${source.chunkPath}`;\n break;\n case SourceType.Parent:\n instantiationReason = `because it was required from module ${source.parentId}`;\n break;\n }\n throw new Error(\n `Module ${id} was instantiated ${instantiationReason}, but the module factory is not available. It might have been deleted in an HMR update.`\n );\n }\n\n let parents: ModuleId[];\n switch (source.type) {\n case SourceType.Runtime:\n parents = [];\n break;\n case SourceType.Parent:\n // No need to add this module as a child of the parent module here, this\n // has already been taken care of in `getOrInstantiateModuleFromParent`.\n parents = [source.parentId];\n break;\n }\n\n const module: Module = {\n exports: {},\n error: undefined,\n loaded: false,\n id,\n parents,\n children: [],\n namespaceObject: undefined,\n };\n moduleCache[id] = module;\n\n // NOTE(alexkirsz) This can fail when the module encounters a runtime error.\n try {\n const r = commonJsRequire.bind(null, module);\n moduleFactory.call(module.exports, {\n a: asyncModule.bind(null, module),\n e: module.exports,\n r,\n t: runtimeRequire,\n x: externalRequire,\n y: externalImport,\n f: moduleContext,\n i: esmImport.bind(null, module),\n s: esmExport.bind(null, module, module.exports),\n j: dynamicExport.bind(null, module, module.exports),\n v: exportValue.bind(null, module),\n n: exportNamespace.bind(null, module),\n m: module,\n c: moduleCache,\n M: moduleFactories,\n l: loadChunkAsync.bind(null, { type: SourceType.Parent, parentId: id }),\n w: loadWebAssembly,\n u: loadWebAssemblyModule,\n g: globalThis,\n P: resolveAbsolutePath,\n U: relativeURL,\n R: createResolvePathFromModule(r),\n __dirname: module.id.replace(/(^|\\/)[\\/]+$/, \"\"),\n });\n } catch (error) {\n module.error = error as any;\n throw error;\n }\n\n module.loaded = true;\n if (module.namespaceObject && module.exports !== module.namespaceObject) {\n // in case of a circular dependency: cjs1 -> esm2 -> cjs1\n interopEsm(module.exports, module.namespaceObject);\n }\n\n return module;\n}\n\n/**\n * Retrieves a module from the cache, or instantiate it if it is not cached.\n */\nfunction getOrInstantiateModuleFromParent(\n id: ModuleId,\n sourceModule: Module\n): Module {\n const module = moduleCache[id];\n\n if (sourceModule.children.indexOf(id) === -1) {\n sourceModule.children.push(id);\n }\n\n if (module) {\n if (module.parents.indexOf(sourceModule.id) === -1) {\n module.parents.push(sourceModule.id);\n }\n\n return module;\n }\n\n return instantiateModule(id, {\n type: SourceType.Parent,\n parentId: sourceModule.id,\n });\n}\n\n/**\n * Instantiates a runtime module.\n */\nfunction instantiateRuntimeModule(\n moduleId: ModuleId,\n chunkPath: ChunkPath\n): Module {\n return instantiateModule(moduleId, { type: SourceType.Runtime, chunkPath });\n}\n\n/**\n * Retrieves a module from the cache, or instantiate it as a runtime module if it is not cached.\n */\nfunction getOrInstantiateRuntimeModule(\n moduleId: ModuleId,\n chunkPath: ChunkPath\n): Module {\n const module = moduleCache[moduleId];\n if (module) {\n if (module.error) {\n throw module.error;\n }\n return module;\n }\n\n return instantiateRuntimeModule(moduleId, chunkPath);\n}\n\nmodule.exports = {\n getOrInstantiateRuntimeModule,\n loadChunk,\n};\n"],"names":[],"mappings":"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"}}] + {"offset": {"line": 3, "column": 0}, "map": {"version":3,"sources":["turbopack://[turbopack]/shared/runtime-utils.ts"],"sourcesContent":["/**\n * This file contains runtime types and functions that are shared between all\n * TurboPack ECMAScript runtimes.\n *\n * It will be prepended to the runtime code of each runtime.\n */\n\n/* eslint-disable @next/next/no-assign-module-variable */\n\n/// \n\ninterface Exports {\n __esModule?: boolean;\n\n [key: string]: any;\n}\n\ntype EsmNamespaceObject = Record;\n\nconst REEXPORTED_OBJECTS = Symbol(\"reexported objects\");\n\ninterface BaseModule {\n exports: Function | Exports | Promise | AsyncModulePromise;\n error: Error | undefined;\n loaded: boolean;\n id: ModuleId;\n children: ModuleId[];\n parents: ModuleId[];\n namespaceObject?:\n | EsmNamespaceObject\n | Promise\n | AsyncModulePromise;\n [REEXPORTED_OBJECTS]?: any[];\n}\n\ninterface Module extends BaseModule {}\n\ntype ModuleContextMap = Record;\n\ninterface ModuleContextEntry {\n id: () => ModuleId;\n module: () => any;\n}\n\ninterface ModuleContext {\n // require call\n (moduleId: ModuleId): Exports | EsmNamespaceObject;\n\n // async import call\n import(moduleId: ModuleId): Promise;\n\n keys(): ModuleId[];\n\n resolve(moduleId: ModuleId): ModuleId;\n}\n\ntype GetOrInstantiateModuleFromParent = (\n moduleId: ModuleId,\n parentModule: Module\n) => Module;\n\nconst hasOwnProperty = Object.prototype.hasOwnProperty;\nconst toStringTag = typeof Symbol !== \"undefined\" && Symbol.toStringTag;\n\nfunction defineProp(\n obj: any,\n name: PropertyKey,\n options: PropertyDescriptor & ThisType\n) {\n if (!hasOwnProperty.call(obj, name))\n Object.defineProperty(obj, name, options);\n}\n\n/**\n * Adds the getters to the exports object.\n */\nfunction esm(exports: Exports, getters: Record any>) {\n defineProp(exports, \"__esModule\", { value: true });\n if (toStringTag) defineProp(exports, toStringTag, { value: \"Module\" });\n for (const key in getters) {\n defineProp(exports, key, { get: getters[key], enumerable: true });\n }\n}\n\n/**\n * Makes the module an ESM with exports\n */\nfunction esmExport(\n module: Module,\n exports: Exports,\n getters: Record any>\n) {\n module.namespaceObject = module.exports;\n esm(exports, getters);\n}\n\nfunction ensureDynamicExports(module: Module, exports: Exports) {\n let reexportedObjects = module[REEXPORTED_OBJECTS];\n\n if (!reexportedObjects) {\n reexportedObjects = module[REEXPORTED_OBJECTS] = [];\n module.exports = module.namespaceObject = new Proxy(exports, {\n get(target, prop) {\n if (\n hasOwnProperty.call(target, prop) ||\n prop === \"default\" ||\n prop === \"__esModule\"\n ) {\n return Reflect.get(target, prop);\n }\n for (const obj of reexportedObjects!) {\n const value = Reflect.get(obj, prop);\n if (value !== undefined) return value;\n }\n return undefined;\n },\n ownKeys(target) {\n const keys = Reflect.ownKeys(target);\n for (const obj of reexportedObjects!) {\n for (const key of Reflect.ownKeys(obj)) {\n if (key !== \"default\" && !keys.includes(key)) keys.push(key);\n }\n }\n return keys;\n },\n });\n }\n}\n\n/**\n * Dynamically exports properties from an object\n */\nfunction dynamicExport(\n module: Module,\n exports: Exports,\n object: Record\n) {\n ensureDynamicExports(module, exports);\n\n if (typeof object === \"object\" && object !== null) {\n module[REEXPORTED_OBJECTS]!.push(object);\n }\n}\n\nfunction exportValue(module: Module, value: any) {\n module.exports = value;\n}\n\nfunction exportNamespace(module: Module, namespace: any) {\n module.exports = module.namespaceObject = namespace;\n}\n\nfunction createGetter(obj: Record, key: string | symbol) {\n return () => obj[key];\n}\n\n/**\n * @returns prototype of the object\n */\nconst getProto: (obj: any) => any = Object.getPrototypeOf\n ? (obj) => Object.getPrototypeOf(obj)\n : (obj) => obj.__proto__;\n\n/** Prototypes that are not expanded for exports */\nconst LEAF_PROTOTYPES = [null, getProto({}), getProto([]), getProto(getProto)];\n\n/**\n * @param raw\n * @param ns\n * @param allowExportDefault\n * * `false`: will have the raw module as default export\n * * `true`: will have the default property as default export\n */\nfunction interopEsm(\n raw: Exports,\n ns: EsmNamespaceObject,\n allowExportDefault?: boolean\n) {\n const getters: { [s: string]: () => any } = Object.create(null);\n for (\n let current = raw;\n (typeof current === \"object\" || typeof current === \"function\") &&\n !LEAF_PROTOTYPES.includes(current);\n current = getProto(current)\n ) {\n for (const key of Object.getOwnPropertyNames(current)) {\n getters[key] = createGetter(raw, key);\n }\n }\n\n // this is not really correct\n // we should set the `default` getter if the imported module is a `.cjs file`\n if (!(allowExportDefault && \"default\" in getters)) {\n getters[\"default\"] = () => raw;\n }\n\n esm(ns, getters);\n return ns;\n}\n\nfunction createNS(raw: BaseModule[\"exports\"]): EsmNamespaceObject {\n if (typeof raw === \"function\") {\n return function (this: any, ...args: any[]) {\n return raw.apply(this, args);\n };\n } else {\n return Object.create(null);\n }\n}\n\nfunction esmImport(\n sourceModule: Module,\n id: ModuleId\n): Exclude {\n const module = getOrInstantiateModuleFromParent(id, sourceModule);\n if (module.error) throw module.error;\n\n // any ES module has to have `module.namespaceObject` defined.\n if (module.namespaceObject) return module.namespaceObject;\n\n // only ESM can be an async module, so we don't need to worry about exports being a promise here.\n const raw = module.exports;\n return (module.namespaceObject = interopEsm(\n raw,\n createNS(raw),\n raw && (raw as any).__esModule\n ));\n}\n\n// Add a simple runtime require so that environments without one can still pass\n// `typeof require` CommonJS checks so that exports are correctly registered.\nconst runtimeRequire =\n typeof require === \"function\"\n ? require\n : function require() {\n throw new Error(\"Unexpected use of runtime require\");\n };\n\nfunction commonJsRequire(sourceModule: Module, id: ModuleId): Exports {\n const module = getOrInstantiateModuleFromParent(id, sourceModule);\n if (module.error) throw module.error;\n return module.exports;\n}\n\n/**\n * `require.context` and require/import expression runtime.\n */\nfunction moduleContext(map: ModuleContextMap): ModuleContext {\n function moduleContext(id: ModuleId): Exports {\n if (hasOwnProperty.call(map, id)) {\n return map[id].module();\n }\n\n const e = new Error(`Cannot find module '${name}'`);\n (e as any).code = \"MODULE_NOT_FOUND\";\n throw e;\n }\n\n moduleContext.keys = (): ModuleId[] => {\n return Object.keys(map);\n };\n\n moduleContext.resolve = (id: ModuleId): ModuleId => {\n if (hasOwnProperty.call(map, id)) {\n return map[id].id();\n }\n\n const e = new Error(`Cannot find module '${name}'`);\n (e as any).code = \"MODULE_NOT_FOUND\";\n throw e;\n };\n\n moduleContext.import = async (id: ModuleId) => {\n return await (moduleContext(id) as Promise);\n };\n\n return moduleContext;\n}\n\n/**\n * Returns the path of a chunk defined by its data.\n */\nfunction getChunkPath(chunkData: ChunkData): ChunkPath {\n return typeof chunkData === \"string\" ? chunkData : chunkData.path;\n}\n\nfunction isPromise(maybePromise: any): maybePromise is Promise {\n return (\n maybePromise != null &&\n typeof maybePromise === \"object\" &&\n \"then\" in maybePromise &&\n typeof maybePromise.then === \"function\"\n );\n}\n\nfunction isAsyncModuleExt(obj: T): obj is AsyncModuleExt & T {\n return turbopackQueues in obj;\n}\n\nfunction createPromise() {\n let resolve: (value: T | PromiseLike) => void;\n let reject: (reason?: any) => void;\n\n const promise = new Promise((res, rej) => {\n reject = rej;\n resolve = res;\n });\n\n return {\n promise,\n resolve: resolve!,\n reject: reject!,\n };\n}\n\n// everything below is adapted from webpack\n// https://github.com/webpack/webpack/blob/6be4065ade1e252c1d8dcba4af0f43e32af1bdc1/lib/runtime/AsyncModuleRuntimeModule.js#L13\n\nconst turbopackQueues = Symbol(\"turbopack queues\");\nconst turbopackExports = Symbol(\"turbopack exports\");\nconst turbopackError = Symbol(\"turbopack error\");\n\ntype AsyncQueueFn = (() => void) & { queueCount: number };\ntype AsyncQueue = AsyncQueueFn[] & { resolved: boolean };\n\nfunction resolveQueue(queue?: AsyncQueue) {\n if (queue && !queue.resolved) {\n queue.resolved = true;\n queue.forEach((fn) => fn.queueCount--);\n queue.forEach((fn) => (fn.queueCount-- ? fn.queueCount++ : fn()));\n }\n}\n\ntype Dep = Exports | AsyncModulePromise | Promise;\n\ntype AsyncModuleExt = {\n [turbopackQueues]: (fn: (queue: AsyncQueue) => void) => void;\n [turbopackExports]: Exports;\n [turbopackError]?: any;\n};\n\ntype AsyncModulePromise = Promise & AsyncModuleExt;\n\nfunction wrapDeps(deps: Dep[]): AsyncModuleExt[] {\n return deps.map((dep) => {\n if (dep !== null && typeof dep === \"object\") {\n if (isAsyncModuleExt(dep)) return dep;\n if (isPromise(dep)) {\n const queue: AsyncQueue = Object.assign([], { resolved: false });\n\n const obj: AsyncModuleExt = {\n [turbopackExports]: {},\n [turbopackQueues]: (fn: (queue: AsyncQueue) => void) => fn(queue),\n };\n\n dep.then(\n (res) => {\n obj[turbopackExports] = res;\n resolveQueue(queue);\n },\n (err) => {\n obj[turbopackError] = err;\n resolveQueue(queue);\n }\n );\n\n return obj;\n }\n }\n\n const ret: AsyncModuleExt = {\n [turbopackExports]: dep,\n [turbopackQueues]: () => {},\n };\n\n return ret;\n });\n}\n\nfunction asyncModule(\n module: Module,\n body: (\n handleAsyncDependencies: (\n deps: Dep[]\n ) => Exports[] | Promise<() => Exports[]>,\n asyncResult: (err?: any) => void\n ) => void,\n hasAwait: boolean\n) {\n const queue: AsyncQueue | undefined = hasAwait\n ? Object.assign([], { resolved: true })\n : undefined;\n\n const depQueues: Set = new Set();\n\n ensureDynamicExports(module, module.exports);\n const exports = module.exports;\n\n const { resolve, reject, promise: rawPromise } = createPromise();\n\n const promise: AsyncModulePromise = Object.assign(rawPromise, {\n [turbopackExports]: exports,\n [turbopackQueues]: (fn) => {\n queue && fn(queue);\n depQueues.forEach(fn);\n promise[\"catch\"](() => {});\n },\n } satisfies AsyncModuleExt);\n\n module.exports = module.namespaceObject = promise;\n\n function handleAsyncDependencies(deps: Dep[]) {\n const currentDeps = wrapDeps(deps);\n\n const getResult = () =>\n currentDeps.map((d) => {\n if (d[turbopackError]) throw d[turbopackError];\n return d[turbopackExports];\n });\n\n const { promise, resolve } = createPromise<() => Exports[]>();\n\n const fn: AsyncQueueFn = Object.assign(() => resolve(getResult), {\n queueCount: 0,\n });\n\n function fnQueue(q: AsyncQueue) {\n if (q !== queue && !depQueues.has(q)) {\n depQueues.add(q);\n if (q && !q.resolved) {\n fn.queueCount++;\n q.push(fn);\n }\n }\n }\n\n currentDeps.map((dep) => dep[turbopackQueues](fnQueue));\n\n return fn.queueCount ? promise : getResult();\n }\n\n function asyncResult(err?: any) {\n if (err) {\n reject((promise[turbopackError] = err));\n } else {\n resolve(exports);\n }\n\n resolveQueue(queue);\n }\n\n body(handleAsyncDependencies, asyncResult);\n\n if (queue) {\n queue.resolved = false;\n }\n}\n\n/**\n * A pseudo \"fake\" URL object to resolve to its relative path.\n *\n * When UrlRewriteBehavior is set to relative, calls to the `new URL()` will construct url without base using this\n * runtime function to generate context-agnostic urls between different rendering context, i.e ssr / client to avoid\n * hydration mismatch.\n *\n * This is based on webpack's existing implementation:\n * https://github.com/webpack/webpack/blob/87660921808566ef3b8796f8df61bd79fc026108/lib/runtime/RelativeUrlRuntimeModule.js\n */\nconst relativeURL = function relativeURL(this: any, inputUrl: string) {\n const realUrl = new URL(inputUrl, \"x:/\");\n const values: Record = {};\n for (const key in realUrl) values[key] = (realUrl as any)[key];\n values.href = inputUrl;\n values.pathname = inputUrl.replace(/[?#].*/, \"\");\n values.origin = values.protocol = \"\";\n values.toString = values.toJSON = (..._args: Array) => inputUrl;\n for (const key in values)\n Object.defineProperty(this, key, {\n enumerable: true,\n configurable: true,\n value: values[key],\n });\n};\n\nrelativeURL.prototype = URL.prototype;\n"],"names":[],"mappings":"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"}}, + {"offset": {"line": 307, "column": 0}, "map": {"version":3,"sources":["turbopack://[turbopack]/shared-node/base-externals-utils.ts"],"sourcesContent":["/// \n\n/// A 'base' utilities to support runtime can have externals.\n/// Currently this is for node.js / edge runtime both.\n/// If a fn requires node.js specific behavior, it should be placed in `node-external-utils` instead.\n\nasync function externalImport(id: ModuleId) {\n let raw;\n try {\n raw = await import(id);\n } catch (err) {\n // TODO(alexkirsz) This can happen when a client-side module tries to load\n // an external module we don't provide a shim for (e.g. querystring, url).\n // For now, we fail semi-silently, but in the future this should be a\n // compilation error.\n throw new Error(`Failed to load external module ${id}: ${err}`);\n }\n\n if (raw && raw.__esModule && raw.default && \"default\" in raw.default) {\n return interopEsm(raw.default, createNS(raw), true);\n }\n\n return raw;\n}\n\nfunction externalRequire(\n id: ModuleId,\n esm: boolean = false\n): Exports | EsmNamespaceObject {\n let raw;\n try {\n raw = require(id);\n } catch (err) {\n // TODO(alexkirsz) This can happen when a client-side module tries to load\n // an external module we don't provide a shim for (e.g. querystring, url).\n // For now, we fail semi-silently, but in the future this should be a\n // compilation error.\n throw new Error(`Failed to load external module ${id}: ${err}`);\n }\n\n if (!esm || raw.__esModule) {\n return raw;\n }\n\n return interopEsm(raw, createNS(raw), true);\n}\n\nexternalRequire.resolve = (\n id: string,\n options?: {\n paths?: string[];\n }\n) => {\n return require.resolve(id, options);\n};\n"],"names":[],"mappings":"AAAA,mDAAmD;AAEnD,6DAA6D;AAC7D,sDAAsD;AACtD,qGAAqG;AAErG,eAAe,eAAe,EAAY;IACxC,IAAI;IACJ,IAAI;QACF,MAAM,MAAM,MAAM,CAAC;IACrB,EAAE,OAAO,KAAK;QACZ,0EAA0E;QAC1E,0EAA0E;QAC1E,qEAAqE;QACrE,qBAAqB;QACrB,MAAM,IAAI,MAAM,CAAC,+BAA+B,EAAE,GAAG,EAAE,EAAE,IAAI,CAAC;IAChE;IAEA,IAAI,OAAO,IAAI,UAAU,IAAI,IAAI,OAAO,IAAI,aAAa,IAAI,OAAO,EAAE;QACpE,OAAO,WAAW,IAAI,OAAO,EAAE,SAAS,MAAM;IAChD;IAEA,OAAO;AACT;AAEA,SAAS,gBACP,EAAY,EACZ,MAAe,KAAK;IAEpB,IAAI;IACJ,IAAI;QACF,MAAM,QAAQ;IAChB,EAAE,OAAO,KAAK;QACZ,0EAA0E;QAC1E,0EAA0E;QAC1E,qEAAqE;QACrE,qBAAqB;QACrB,MAAM,IAAI,MAAM,CAAC,+BAA+B,EAAE,GAAG,EAAE,EAAE,IAAI,CAAC;IAChE;IAEA,IAAI,CAAC,OAAO,IAAI,UAAU,EAAE;QAC1B,OAAO;IACT;IAEA,OAAO,WAAW,KAAK,SAAS,MAAM;AACxC;AAEA,gBAAgB,OAAO,GAAG,CACxB,IACA;IAIA,OAAO,QAAQ,OAAO,CAAC,IAAI;AAC7B"}}, + {"offset": {"line": 346, "column": 0}, "map": {"version":3,"sources":["turbopack://[turbopack]/shared-node/node-externals-utils.ts"],"sourcesContent":["declare var RUNTIME_PUBLIC_PATH: string;\ndeclare var OUTPUT_ROOT: string;\ndeclare var ASSET_PREFIX: string;\n\nconst path = require(\"path\");\n\nconst relativePathToRuntimeRoot = path.relative(RUNTIME_PUBLIC_PATH, \".\");\n// Compute the relative path to the `distDir`.\nconst relativePathToDistRoot = path.relative(\n path.join(OUTPUT_ROOT, RUNTIME_PUBLIC_PATH),\n \".\"\n);\nconst RUNTIME_ROOT = path.resolve(__filename, relativePathToRuntimeRoot);\n// Compute the absolute path to the root, by stripping distDir from the absolute path to this file.\nconst ABSOLUTE_ROOT = path.resolve(__filename, relativePathToDistRoot);\n\n/**\n * Returns an absolute path to the given module path.\n * Module path should be relative, either path to a file or a directory.\n *\n * This fn allows to calculate an absolute path for some global static values, such as\n * `__dirname` or `import.meta.url` that Turbopack will not embeds in compile time.\n * See ImportMetaBinding::code_generation for the usage.\n */\nfunction resolveAbsolutePath(modulePath?: string): string {\n if (modulePath) {\n return path.join(ABSOLUTE_ROOT, modulePath);\n }\n return ABSOLUTE_ROOT;\n}\n"],"names":[],"mappings":"AAIA,MAAM,OAAO,QAAQ;AAErB,MAAM,4BAA4B,KAAK,QAAQ,CAAC,qBAAqB;AACrE,8CAA8C;AAC9C,MAAM,yBAAyB,KAAK,QAAQ,CAC1C,KAAK,IAAI,CAAC,aAAa,sBACvB;AAEF,MAAM,eAAe,KAAK,OAAO,CAAC,YAAY;AAC9C,mGAAmG;AACnG,MAAM,gBAAgB,KAAK,OAAO,CAAC,YAAY;AAE/C;;;;;;;CAOC,GACD,SAAS,oBAAoB,UAAmB;IAC9C,IAAI,YAAY;QACd,OAAO,KAAK,IAAI,CAAC,eAAe;IAClC;IACA,OAAO;AACT"}}, + {"offset": {"line": 366, "column": 0}, "map": {"version":3,"sources":["turbopack://[turbopack]/shared-node/node-wasm-utils.ts"],"sourcesContent":["/// \n\nfunction readWebAssemblyAsResponse(path: string) {\n const { createReadStream } = require(\"fs\") as typeof import(\"fs\");\n const { Readable } = require(\"stream\") as typeof import(\"stream\");\n\n const stream = createReadStream(path);\n\n // @ts-ignore unfortunately there's a slight type mismatch with the stream.\n return new Response(Readable.toWeb(stream), {\n headers: {\n \"content-type\": \"application/wasm\",\n },\n });\n}\n\nasync function compileWebAssemblyFromPath(\n path: string\n): Promise {\n const response = readWebAssemblyAsResponse(path);\n\n return await WebAssembly.compileStreaming(response);\n}\n\nasync function instantiateWebAssemblyFromPath(\n path: string,\n importsObj: WebAssembly.Imports\n): Promise {\n const response = readWebAssemblyAsResponse(path);\n\n const { instance } = await WebAssembly.instantiateStreaming(\n response,\n importsObj\n );\n\n return instance.exports;\n}\n"],"names":[],"mappings":"AAAA,mDAAmD;AAEnD,SAAS,0BAA0B,IAAY;IAC7C,MAAM,EAAE,gBAAgB,EAAE,GAAG,QAAQ;IACrC,MAAM,EAAE,QAAQ,EAAE,GAAG,QAAQ;IAE7B,MAAM,SAAS,iBAAiB;IAEhC,2EAA2E;IAC3E,OAAO,IAAI,SAAS,SAAS,KAAK,CAAC,SAAS;QAC1C,SAAS;YACP,gBAAgB;QAClB;IACF;AACF;AAEA,eAAe,2BACb,IAAY;IAEZ,MAAM,WAAW,0BAA0B;IAE3C,OAAO,MAAM,YAAY,gBAAgB,CAAC;AAC5C;AAEA,eAAe,+BACb,IAAY,EACZ,UAA+B;IAE/B,MAAM,WAAW,0BAA0B;IAE3C,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,YAAY,oBAAoB,CACzD,UACA;IAGF,OAAO,SAAS,OAAO;AACzB"}}, + {"offset": {"line": 387, "column": 0}, "map": {"version":3,"sources":["turbopack://[turbopack]/build/runtime.ts"],"sourcesContent":["/// \n/// \n/// \n/// \n\nenum SourceType {\n /**\n * The module was instantiated because it was included in an evaluated chunk's\n * runtime.\n */\n Runtime = 0,\n /**\n * The module was instantiated because a parent module imported it.\n */\n Parent = 1,\n}\n\ntype SourceInfo =\n | {\n type: SourceType.Runtime;\n chunkPath: ChunkPath;\n }\n | {\n type: SourceType.Parent;\n parentId: ModuleId;\n };\n\nfunction stringifySourceInfo(source: SourceInfo): string {\n switch (source.type) {\n case SourceType.Runtime:\n return `runtime for chunk ${source.chunkPath}`;\n case SourceType.Parent:\n return `parent module ${source.parentId}`;\n }\n}\n\ntype ExternalRequire = (id: ModuleId) => Exports | EsmNamespaceObject;\ntype ExternalImport = (id: ModuleId) => Promise;\ntype ResolveAbsolutePath = (modulePath?: string) => string;\n\ninterface TurbopackNodeBuildContext extends TurbopackBaseContext {\n P: ResolveAbsolutePath;\n R: ResolvePathFromModule;\n x: ExternalRequire;\n y: ExternalImport;\n}\n\ntype ModuleFactory = (\n this: Module[\"exports\"],\n context: TurbopackNodeBuildContext\n) => undefined;\n\nconst url = require(\"url\");\n\nconst moduleFactories: ModuleFactories = Object.create(null);\nconst moduleCache: ModuleCache = Object.create(null);\n\n/**\n * Returns an absolute path to the given module's id.\n */\nfunction createResolvePathFromModule(\n resolver: (moduleId: string) => Exports\n): (moduleId: string) => string {\n return function resolvePathFromModule(moduleId: string): string {\n const exported = resolver(moduleId);\n const exportedPath = exported?.default ?? exported;\n if (typeof exportedPath !== \"string\") {\n return exported as any;\n }\n\n const strippedAssetPrefix = exportedPath.slice(ASSET_PREFIX.length);\n const resolved = path.resolve(\n ABSOLUTE_ROOT,\n OUTPUT_ROOT,\n strippedAssetPrefix\n );\n\n return url.pathToFileURL(resolved);\n };\n}\n\nfunction loadChunk(chunkData: ChunkData, source?: SourceInfo): void {\n if (typeof chunkData === \"string\") {\n return loadChunkPath(chunkData, source);\n } else {\n return loadChunkPath(chunkData.path, source);\n }\n}\n\nfunction loadChunkPath(chunkPath: ChunkPath, source?: SourceInfo): void {\n if (!chunkPath.endsWith(\".js\")) {\n // We only support loading JS chunks in Node.js.\n // This branch can be hit when trying to load a CSS chunk.\n return;\n }\n\n try {\n const resolved = path.resolve(RUNTIME_ROOT, chunkPath);\n const chunkModules: ModuleFactories = require(resolved);\n\n for (const [moduleId, moduleFactory] of Object.entries(chunkModules)) {\n if (!moduleFactories[moduleId]) {\n moduleFactories[moduleId] = moduleFactory;\n }\n }\n } catch (e) {\n let errorMessage = `Failed to load chunk ${chunkPath}`;\n\n if (source) {\n errorMessage += ` from ${stringifySourceInfo(source)}`;\n }\n\n throw new Error(errorMessage, {\n cause: e,\n });\n }\n}\n\nasync function loadChunkAsync(\n source: SourceInfo,\n chunkData: ChunkData\n): Promise {\n return new Promise((resolve, reject) => {\n try {\n loadChunk(chunkData, source);\n } catch (err) {\n reject(err);\n return;\n }\n resolve();\n });\n}\n\nfunction loadWebAssembly(chunkPath: ChunkPath, imports: WebAssembly.Imports) {\n const resolved = path.resolve(RUNTIME_ROOT, chunkPath);\n\n return instantiateWebAssemblyFromPath(resolved, imports);\n}\n\nfunction loadWebAssemblyModule(chunkPath: ChunkPath) {\n const resolved = path.resolve(RUNTIME_ROOT, chunkPath);\n\n return compileWebAssemblyFromPath(resolved);\n}\n\nfunction instantiateModule(id: ModuleId, source: SourceInfo): Module {\n const moduleFactory = moduleFactories[id];\n if (typeof moduleFactory !== \"function\") {\n // This can happen if modules incorrectly handle HMR disposes/updates,\n // e.g. when they keep a `setTimeout` around which still executes old code\n // and contains e.g. a `require(\"something\")` call.\n let instantiationReason;\n switch (source.type) {\n case SourceType.Runtime:\n instantiationReason = `as a runtime entry of chunk ${source.chunkPath}`;\n break;\n case SourceType.Parent:\n instantiationReason = `because it was required from module ${source.parentId}`;\n break;\n }\n throw new Error(\n `Module ${id} was instantiated ${instantiationReason}, but the module factory is not available. It might have been deleted in an HMR update.`\n );\n }\n\n let parents: ModuleId[];\n switch (source.type) {\n case SourceType.Runtime:\n parents = [];\n break;\n case SourceType.Parent:\n // No need to add this module as a child of the parent module here, this\n // has already been taken care of in `getOrInstantiateModuleFromParent`.\n parents = [source.parentId];\n break;\n }\n\n const module: Module = {\n exports: {},\n error: undefined,\n loaded: false,\n id,\n parents,\n children: [],\n namespaceObject: undefined,\n };\n moduleCache[id] = module;\n\n // NOTE(alexkirsz) This can fail when the module encounters a runtime error.\n try {\n const r = commonJsRequire.bind(null, module);\n moduleFactory.call(module.exports, {\n a: asyncModule.bind(null, module),\n e: module.exports,\n r,\n t: runtimeRequire,\n x: externalRequire,\n y: externalImport,\n f: moduleContext,\n i: esmImport.bind(null, module),\n s: esmExport.bind(null, module, module.exports),\n j: dynamicExport.bind(null, module, module.exports),\n v: exportValue.bind(null, module),\n n: exportNamespace.bind(null, module),\n m: module,\n c: moduleCache,\n M: moduleFactories,\n l: loadChunkAsync.bind(null, { type: SourceType.Parent, parentId: id }),\n w: loadWebAssembly,\n u: loadWebAssemblyModule,\n g: globalThis,\n P: resolveAbsolutePath,\n U: relativeURL,\n R: createResolvePathFromModule(r),\n __dirname: module.id.replace(/(^|\\/)[\\/]+$/, \"\"),\n });\n } catch (error) {\n module.error = error as any;\n throw error;\n }\n\n module.loaded = true;\n if (module.namespaceObject && module.exports !== module.namespaceObject) {\n // in case of a circular dependency: cjs1 -> esm2 -> cjs1\n interopEsm(module.exports, module.namespaceObject);\n }\n\n return module;\n}\n\n/**\n * Retrieves a module from the cache, or instantiate it if it is not cached.\n */\nfunction getOrInstantiateModuleFromParent(\n id: ModuleId,\n sourceModule: Module\n): Module {\n const module = moduleCache[id];\n\n if (sourceModule.children.indexOf(id) === -1) {\n sourceModule.children.push(id);\n }\n\n if (module) {\n if (module.parents.indexOf(sourceModule.id) === -1) {\n module.parents.push(sourceModule.id);\n }\n\n return module;\n }\n\n return instantiateModule(id, {\n type: SourceType.Parent,\n parentId: sourceModule.id,\n });\n}\n\n/**\n * Instantiates a runtime module.\n */\nfunction instantiateRuntimeModule(\n moduleId: ModuleId,\n chunkPath: ChunkPath\n): Module {\n return instantiateModule(moduleId, { type: SourceType.Runtime, chunkPath });\n}\n\n/**\n * Retrieves a module from the cache, or instantiate it as a runtime module if it is not cached.\n */\nfunction getOrInstantiateRuntimeModule(\n moduleId: ModuleId,\n chunkPath: ChunkPath\n): Module {\n const module = moduleCache[moduleId];\n if (module) {\n if (module.error) {\n throw module.error;\n }\n return module;\n }\n\n return instantiateRuntimeModule(moduleId, chunkPath);\n}\n\nmodule.exports = {\n getOrInstantiateRuntimeModule,\n loadChunk,\n};\n"],"names":[],"mappings":"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"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/runtime/default_dev_runtime/output/79fb1_turbopack-tests_tests_snapshot_runtime_default_dev_runtime_input_index_40d141.js.map b/crates/turbopack-tests/tests/snapshot/runtime/default_dev_runtime/output/79fb1_turbopack-tests_tests_snapshot_runtime_default_dev_runtime_input_index_40d141.js.map index 9ba0bde1d90d1..acac954d76c5d 100644 --- a/crates/turbopack-tests/tests/snapshot/runtime/default_dev_runtime/output/79fb1_turbopack-tests_tests_snapshot_runtime_default_dev_runtime_input_index_40d141.js.map +++ b/crates/turbopack-tests/tests/snapshot/runtime/default_dev_runtime/output/79fb1_turbopack-tests_tests_snapshot_runtime_default_dev_runtime_input_index_40d141.js.map @@ -2,8 +2,8 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 13, "column": 0}, "map": {"version":3,"sources":["/turbopack/[turbopack]/shared/runtime-utils.ts"],"sourcesContent":["/**\n * This file contains runtime types and functions that are shared between all\n * TurboPack ECMAScript runtimes.\n *\n * It will be prepended to the runtime code of each runtime.\n */\n\n/* eslint-disable @next/next/no-assign-module-variable */\n\n/// \n\ninterface Exports {\n __esModule?: boolean;\n\n [key: string]: any;\n}\n\ntype EsmNamespaceObject = Record;\n\nconst REEXPORTED_OBJECTS = Symbol(\"reexported objects\");\n\ninterface BaseModule {\n exports: Function | Exports | Promise | AsyncModulePromise;\n error: Error | undefined;\n loaded: boolean;\n id: ModuleId;\n children: ModuleId[];\n parents: ModuleId[];\n namespaceObject?:\n | EsmNamespaceObject\n | Promise\n | AsyncModulePromise;\n [REEXPORTED_OBJECTS]?: any[];\n}\n\ninterface Module extends BaseModule {}\n\ntype ModuleContextMap = Record;\n\ninterface ModuleContextEntry {\n id: () => ModuleId;\n module: () => any;\n}\n\ninterface ModuleContext {\n // require call\n (moduleId: ModuleId): Exports | EsmNamespaceObject;\n\n // async import call\n import(moduleId: ModuleId): Promise;\n\n keys(): ModuleId[];\n\n resolve(moduleId: ModuleId): ModuleId;\n}\n\ntype GetOrInstantiateModuleFromParent = (\n moduleId: ModuleId,\n parentModule: Module\n) => Module;\n\nconst hasOwnProperty = Object.prototype.hasOwnProperty;\nconst toStringTag = typeof Symbol !== \"undefined\" && Symbol.toStringTag;\n\nfunction defineProp(\n obj: any,\n name: PropertyKey,\n options: PropertyDescriptor & ThisType\n) {\n if (!hasOwnProperty.call(obj, name))\n Object.defineProperty(obj, name, options);\n}\n\n/**\n * Adds the getters to the exports object.\n */\nfunction esm(exports: Exports, getters: Record any>) {\n defineProp(exports, \"__esModule\", { value: true });\n if (toStringTag) defineProp(exports, toStringTag, { value: \"Module\" });\n for (const key in getters) {\n defineProp(exports, key, { get: getters[key], enumerable: true });\n }\n}\n\n/**\n * Makes the module an ESM with exports\n */\nfunction esmExport(\n module: Module,\n exports: Exports,\n getters: Record any>\n) {\n module.namespaceObject = module.exports;\n esm(exports, getters);\n}\n\nfunction ensureDynamicExports(module: Module, exports: Exports) {\n let reexportedObjects = module[REEXPORTED_OBJECTS];\n\n if (!reexportedObjects) {\n reexportedObjects = module[REEXPORTED_OBJECTS] = [];\n module.exports = module.namespaceObject = new Proxy(exports, {\n get(target, prop) {\n if (\n hasOwnProperty.call(target, prop) ||\n prop === \"default\" ||\n prop === \"__esModule\"\n ) {\n return Reflect.get(target, prop);\n }\n for (const obj of reexportedObjects!) {\n const value = Reflect.get(obj, prop);\n if (value !== undefined) return value;\n }\n return undefined;\n },\n ownKeys(target) {\n const keys = Reflect.ownKeys(target);\n for (const obj of reexportedObjects!) {\n for (const key of Reflect.ownKeys(obj)) {\n if (key !== \"default\" && !keys.includes(key)) keys.push(key);\n }\n }\n return keys;\n },\n });\n }\n}\n\n/**\n * Dynamically exports properties from an object\n */\nfunction dynamicExport(\n module: Module,\n exports: Exports,\n object: Record\n) {\n ensureDynamicExports(module, exports);\n\n if (typeof object === \"object\" && object !== null) {\n module[REEXPORTED_OBJECTS]!.push(object);\n }\n}\n\nfunction exportValue(module: Module, value: any) {\n module.exports = value;\n}\n\nfunction exportNamespace(module: Module, namespace: any) {\n module.exports = module.namespaceObject = namespace;\n}\n\nfunction createGetter(obj: Record, key: string | symbol) {\n return () => obj[key];\n}\n\n/**\n * @returns prototype of the object\n */\nconst getProto: (obj: any) => any = Object.getPrototypeOf\n ? (obj) => Object.getPrototypeOf(obj)\n : (obj) => obj.__proto__;\n\n/** Prototypes that are not expanded for exports */\nconst LEAF_PROTOTYPES = [null, getProto({}), getProto([]), getProto(getProto)];\n\n/**\n * @param raw\n * @param ns\n * @param allowExportDefault\n * * `false`: will have the raw module as default export\n * * `true`: will have the default property as default export\n */\nfunction interopEsm(\n raw: Exports,\n ns: EsmNamespaceObject,\n allowExportDefault?: boolean\n) {\n const getters: { [s: string]: () => any } = Object.create(null);\n for (\n let current = raw;\n (typeof current === \"object\" || typeof current === \"function\") &&\n !LEAF_PROTOTYPES.includes(current);\n current = getProto(current)\n ) {\n for (const key of Object.getOwnPropertyNames(current)) {\n getters[key] = createGetter(raw, key);\n }\n }\n\n // this is not really correct\n // we should set the `default` getter if the imported module is a `.cjs file`\n if (!(allowExportDefault && \"default\" in getters)) {\n getters[\"default\"] = () => raw;\n }\n\n esm(ns, getters);\n return ns;\n}\n\nfunction createNS(raw: BaseModule[\"exports\"]): EsmNamespaceObject {\n if (typeof raw === \"function\") {\n return function (this: any, ...args: any[]) {\n return raw.apply(this, args);\n };\n } else {\n return Object.create(null);\n }\n}\n\nfunction esmImport(\n sourceModule: Module,\n id: ModuleId\n): Exclude {\n const module = getOrInstantiateModuleFromParent(id, sourceModule);\n if (module.error) throw module.error;\n\n // any ES module has to have `module.namespaceObject` defined.\n if (module.namespaceObject) return module.namespaceObject;\n\n // only ESM can be an async module, so we don't need to worry about exports being a promise here.\n const raw = module.exports;\n return (module.namespaceObject = interopEsm(\n raw,\n createNS(raw),\n raw && (raw as any).__esModule\n ));\n}\n\n// Add a simple runtime require so that environments without one can still pass\n// `typeof require` CommonJS checks so that exports are correctly registered.\nconst runtimeRequire =\n typeof require === \"function\"\n ? require\n : function require() {\n throw new Error(\"Unexpected use of runtime require\");\n };\n\nfunction commonJsRequire(sourceModule: Module, id: ModuleId): Exports {\n const module = getOrInstantiateModuleFromParent(id, sourceModule);\n if (module.error) throw module.error;\n return module.exports;\n}\n\n/**\n * `require.context` and require/import expression runtime.\n */\nfunction moduleContext(map: ModuleContextMap): ModuleContext {\n function moduleContext(id: ModuleId): Exports {\n if (hasOwnProperty.call(map, id)) {\n return map[id].module();\n }\n\n const e = new Error(`Cannot find module '${name}'`);\n (e as any).code = \"MODULE_NOT_FOUND\";\n throw e;\n }\n\n moduleContext.keys = (): ModuleId[] => {\n return Object.keys(map);\n };\n\n moduleContext.resolve = (id: ModuleId): ModuleId => {\n if (hasOwnProperty.call(map, id)) {\n return map[id].id();\n }\n\n const e = new Error(`Cannot find module '${name}'`);\n (e as any).code = \"MODULE_NOT_FOUND\";\n throw e;\n };\n\n moduleContext.import = async (id: ModuleId) => {\n return await (moduleContext(id) as Promise);\n };\n\n return moduleContext;\n}\n\n/**\n * Returns the path of a chunk defined by its data.\n */\nfunction getChunkPath(chunkData: ChunkData): ChunkPath {\n return typeof chunkData === \"string\" ? chunkData : chunkData.path;\n}\n\nfunction isPromise(maybePromise: any): maybePromise is Promise {\n return (\n maybePromise != null &&\n typeof maybePromise === \"object\" &&\n \"then\" in maybePromise &&\n typeof maybePromise.then === \"function\"\n );\n}\n\nfunction isAsyncModuleExt(obj: T): obj is AsyncModuleExt & T {\n return turbopackQueues in obj;\n}\n\nfunction createPromise() {\n let resolve: (value: T | PromiseLike) => void;\n let reject: (reason?: any) => void;\n\n const promise = new Promise((res, rej) => {\n reject = rej;\n resolve = res;\n });\n\n return {\n promise,\n resolve: resolve!,\n reject: reject!,\n };\n}\n\n// everything below is adapted from webpack\n// https://github.com/webpack/webpack/blob/6be4065ade1e252c1d8dcba4af0f43e32af1bdc1/lib/runtime/AsyncModuleRuntimeModule.js#L13\n\nconst turbopackQueues = Symbol(\"turbopack queues\");\nconst turbopackExports = Symbol(\"turbopack exports\");\nconst turbopackError = Symbol(\"turbopack error\");\n\ntype AsyncQueueFn = (() => void) & { queueCount: number };\ntype AsyncQueue = AsyncQueueFn[] & { resolved: boolean };\n\nfunction resolveQueue(queue?: AsyncQueue) {\n if (queue && !queue.resolved) {\n queue.resolved = true;\n queue.forEach((fn) => fn.queueCount--);\n queue.forEach((fn) => (fn.queueCount-- ? fn.queueCount++ : fn()));\n }\n}\n\ntype Dep = Exports | AsyncModulePromise | Promise;\n\ntype AsyncModuleExt = {\n [turbopackQueues]: (fn: (queue: AsyncQueue) => void) => void;\n [turbopackExports]: Exports;\n [turbopackError]?: any;\n};\n\ntype AsyncModulePromise = Promise & AsyncModuleExt;\n\nfunction wrapDeps(deps: Dep[]): AsyncModuleExt[] {\n return deps.map((dep) => {\n if (dep !== null && typeof dep === \"object\") {\n if (isAsyncModuleExt(dep)) return dep;\n if (isPromise(dep)) {\n const queue: AsyncQueue = Object.assign([], { resolved: false });\n\n const obj: AsyncModuleExt = {\n [turbopackExports]: {},\n [turbopackQueues]: (fn: (queue: AsyncQueue) => void) => fn(queue),\n };\n\n dep.then(\n (res) => {\n obj[turbopackExports] = res;\n resolveQueue(queue);\n },\n (err) => {\n obj[turbopackError] = err;\n resolveQueue(queue);\n }\n );\n\n return obj;\n }\n }\n\n const ret: AsyncModuleExt = {\n [turbopackExports]: dep,\n [turbopackQueues]: () => {},\n };\n\n return ret;\n });\n}\n\nfunction asyncModule(\n module: Module,\n body: (\n handleAsyncDependencies: (\n deps: Dep[]\n ) => Exports[] | Promise<() => Exports[]>,\n asyncResult: (err?: any) => void\n ) => void,\n hasAwait: boolean\n) {\n const queue: AsyncQueue | undefined = hasAwait\n ? Object.assign([], { resolved: true })\n : undefined;\n\n const depQueues: Set = new Set();\n\n ensureDynamicExports(module, module.exports);\n const exports = module.exports;\n\n const { resolve, reject, promise: rawPromise } = createPromise();\n\n const promise: AsyncModulePromise = Object.assign(rawPromise, {\n [turbopackExports]: exports,\n [turbopackQueues]: (fn) => {\n queue && fn(queue);\n depQueues.forEach(fn);\n promise[\"catch\"](() => {});\n },\n } satisfies AsyncModuleExt);\n\n module.exports = module.namespaceObject = promise;\n\n function handleAsyncDependencies(deps: Dep[]) {\n const currentDeps = wrapDeps(deps);\n\n const getResult = () =>\n currentDeps.map((d) => {\n if (d[turbopackError]) throw d[turbopackError];\n return d[turbopackExports];\n });\n\n const { promise, resolve } = createPromise<() => Exports[]>();\n\n const fn: AsyncQueueFn = Object.assign(() => resolve(getResult), {\n queueCount: 0,\n });\n\n function fnQueue(q: AsyncQueue) {\n if (q !== queue && !depQueues.has(q)) {\n depQueues.add(q);\n if (q && !q.resolved) {\n fn.queueCount++;\n q.push(fn);\n }\n }\n }\n\n currentDeps.map((dep) => dep[turbopackQueues](fnQueue));\n\n return fn.queueCount ? promise : getResult();\n }\n\n function asyncResult(err?: any) {\n if (err) {\n reject((promise[turbopackError] = err));\n } else {\n resolve(exports);\n }\n\n resolveQueue(queue);\n }\n\n body(handleAsyncDependencies, asyncResult);\n\n if (queue) {\n queue.resolved = false;\n }\n}\n\n/**\n * A pseudo \"fake\" URL object to resolve to its relative path.\n *\n * When UrlRewriteBehavior is set to relative, calls to the `new URL()` will construct url without base using this\n * runtime function to generate context-agnostic urls between different rendering context, i.e ssr / client to avoid\n * hydration mismatch.\n *\n * This is based on webpack's existing implementation:\n * https://github.com/webpack/webpack/blob/87660921808566ef3b8796f8df61bd79fc026108/lib/runtime/RelativeUrlRuntimeModule.js\n */\nconst relativeURL = function relativeURL(this: any, inputUrl: string) {\n const realUrl = new URL(inputUrl, \"x:/\");\n const values: Record = {};\n for (const key in realUrl) values[key] = (realUrl as any)[key];\n values.href = inputUrl;\n values.pathname = inputUrl.replace(/[?#].*/, \"\");\n values.origin = values.protocol = \"\";\n values.toString = values.toJSON = (..._args: Array) => inputUrl;\n for (const key in values)\n Object.defineProperty(this, key, {\n enumerable: true,\n configurable: true,\n value: values[key],\n });\n};\n\nrelativeURL.prototype = URL.prototype;\n"],"names":[],"mappings":"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"}}, - {"offset": {"line": 317, "column": 0}, "map": {"version":3,"sources":["/turbopack/[turbopack]/dev/runtime/base/runtime-base.ts"],"sourcesContent":["/**\n * This file contains runtime types and functions that are shared between all\n * Turbopack *development* ECMAScript runtimes.\n *\n * It will be appended to the runtime code of each runtime right after the\n * shared runtime utils.\n */\n\n/* eslint-disable @next/next/no-assign-module-variable */\n\n/// \n/// \n/// \n/// \n\n// This file must not use `import` and `export` statements. Otherwise, it\n// becomes impossible to augment interfaces declared in ``d files\n// (e.g. `Module`). Hence, the need for `import()` here.\ntype RefreshRuntimeGlobals =\n import(\"@next/react-refresh-utils/dist/runtime\").RefreshRuntimeGlobals;\n\ndeclare var CHUNK_BASE_PATH: string;\ndeclare var $RefreshHelpers$: RefreshRuntimeGlobals[\"$RefreshHelpers$\"];\ndeclare var $RefreshReg$: RefreshRuntimeGlobals[\"$RefreshReg$\"];\ndeclare var $RefreshSig$: RefreshRuntimeGlobals[\"$RefreshSig$\"];\ndeclare var $RefreshInterceptModuleExecution$:\n | RefreshRuntimeGlobals[\"$RefreshInterceptModuleExecution$\"];\n\ntype RefreshContext = {\n register: RefreshRuntimeGlobals[\"$RefreshReg$\"];\n signature: RefreshRuntimeGlobals[\"$RefreshSig$\"];\n};\n\ntype RefreshHelpers = RefreshRuntimeGlobals[\"$RefreshHelpers$\"];\n\ninterface TurbopackDevBaseContext extends TurbopackBaseContext {\n k: RefreshContext;\n R: ResolvePathFromModule;\n}\n\ninterface TurbopackDevContext extends TurbopackDevBaseContext {}\n\n// string encoding of a module factory (used in hmr updates)\ntype ModuleFactoryString = string;\n\ntype ModuleFactory = (\n this: Module[\"exports\"],\n context: TurbopackDevContext\n) => undefined;\n\ntype DevRuntimeParams = {\n otherChunks: ChunkData[];\n runtimeModuleIds: ModuleId[];\n};\n\ntype ChunkRegistration = [\n chunkPath: ChunkPath,\n chunkModules: ModuleFactories,\n params: DevRuntimeParams | undefined\n];\ntype ChunkList = {\n path: ChunkPath;\n chunks: ChunkData[];\n source: \"entry\" | \"dynamic\";\n};\n\nenum SourceType {\n /**\n * The module was instantiated because it was included in an evaluated chunk's\n * runtime.\n */\n Runtime = 0,\n /**\n * The module was instantiated because a parent module imported it.\n */\n Parent = 1,\n /**\n * The module was instantiated because it was included in a chunk's hot module\n * update.\n */\n Update = 2,\n}\n\ntype SourceInfo =\n | {\n type: SourceType.Runtime;\n chunkPath: ChunkPath;\n }\n | {\n type: SourceType.Parent;\n parentId: ModuleId;\n }\n | {\n type: SourceType.Update;\n parents?: ModuleId[];\n };\n\ninterface RuntimeBackend {\n registerChunk: (chunkPath: ChunkPath, params?: DevRuntimeParams) => void;\n loadChunk: (chunkPath: ChunkPath, source: SourceInfo) => Promise;\n reloadChunk?: (chunkPath: ChunkPath) => Promise;\n unloadChunk?: (chunkPath: ChunkPath) => void;\n\n restart: () => void;\n}\n\nclass UpdateApplyError extends Error {\n name = \"UpdateApplyError\";\n\n dependencyChain: string[];\n\n constructor(message: string, dependencyChain: string[]) {\n super(message);\n this.dependencyChain = dependencyChain;\n }\n}\n\nconst moduleFactories: ModuleFactories = Object.create(null);\nconst moduleCache: ModuleCache = Object.create(null);\n/**\n * Maps module IDs to persisted data between executions of their hot module\n * implementation (`hot.data`).\n */\nconst moduleHotData: Map = new Map();\n/**\n * Maps module instances to their hot module state.\n */\nconst moduleHotState: Map = new Map();\n/**\n * Modules that call `module.hot.invalidate()` (while being updated).\n */\nconst queuedInvalidatedModules: Set = new Set();\n/**\n * Module IDs that are instantiated as part of the runtime of a chunk.\n */\nconst runtimeModules: Set = new Set();\n/**\n * Map from module ID to the chunks that contain this module.\n *\n * In HMR, we need to keep track of which modules are contained in which so\n * chunks. This is so we don't eagerly dispose of a module when it is removed\n * from chunk A, but still exists in chunk B.\n */\nconst moduleChunksMap: Map> = new Map();\n/**\n * Map from a chunk path to all modules it contains.\n */\nconst chunkModulesMap: Map> = new Map();\n/**\n * Chunk lists that contain a runtime. When these chunk lists receive an update\n * that can't be reconciled with the current state of the page, we need to\n * reload the runtime entirely.\n */\nconst runtimeChunkLists: Set = new Set();\n/**\n * Map from a chunk list to the chunk paths it contains.\n */\nconst chunkListChunksMap: Map> = new Map();\n/**\n * Map from a chunk path to the chunk lists it belongs to.\n */\nconst chunkChunkListsMap: Map> = new Map();\n\nconst availableModules: Map | true> = new Map();\n\nconst availableModuleChunks: Map | true> = new Map();\n\nasync function loadChunk(\n source: SourceInfo,\n chunkData: ChunkData\n): Promise {\n if (typeof chunkData === \"string\") {\n return loadChunkPath(source, chunkData);\n }\n\n const includedList = chunkData.included || [];\n const modulesPromises = includedList.map((included) => {\n if (moduleFactories[included]) return true;\n return availableModules.get(included);\n });\n if (modulesPromises.length > 0 && modulesPromises.every((p) => p)) {\n // When all included items are already loaded or loading, we can skip loading ourselves\n return Promise.all(modulesPromises);\n }\n\n const includedModuleChunksList = chunkData.moduleChunks || [];\n const moduleChunksPromises = includedModuleChunksList\n .map((included) => {\n // TODO(alexkirsz) Do we need this check?\n // if (moduleFactories[included]) return true;\n return availableModuleChunks.get(included);\n })\n .filter((p) => p);\n\n let promise;\n if (moduleChunksPromises.length > 0) {\n // Some module chunks are already loaded or loading.\n\n if (moduleChunksPromises.length == includedModuleChunksList.length) {\n // When all included module chunks are already loaded or loading, we can skip loading ourselves\n return Promise.all(moduleChunksPromises);\n }\n\n const moduleChunksToLoad: Set = new Set();\n for (const moduleChunk of includedModuleChunksList) {\n if (!availableModuleChunks.has(moduleChunk)) {\n moduleChunksToLoad.add(moduleChunk);\n }\n }\n\n for (const moduleChunkToLoad of moduleChunksToLoad) {\n const promise = loadChunkPath(source, moduleChunkToLoad);\n\n availableModuleChunks.set(moduleChunkToLoad, promise);\n\n moduleChunksPromises.push(promise);\n }\n\n promise = Promise.all(moduleChunksPromises);\n } else {\n promise = loadChunkPath(source, chunkData.path);\n\n // Mark all included module chunks as loading if they are not already loaded or loading.\n for (const includedModuleChunk of includedModuleChunksList) {\n if (!availableModuleChunks.has(includedModuleChunk)) {\n availableModuleChunks.set(includedModuleChunk, promise);\n }\n }\n }\n\n for (const included of includedList) {\n if (!availableModules.has(included)) {\n // It might be better to race old and new promises, but it's rare that the new promise will be faster than a request started earlier.\n // In production it's even more rare, because the chunk optimization tries to deduplicate modules anyway.\n availableModules.set(included, promise);\n }\n }\n\n return promise;\n}\n\nasync function loadChunkPath(\n source: SourceInfo,\n chunkPath: ChunkPath\n): Promise {\n try {\n await BACKEND.loadChunk(chunkPath, source);\n } catch (error) {\n let loadReason;\n switch (source.type) {\n case SourceType.Runtime:\n loadReason = `as a runtime dependency of chunk ${source.chunkPath}`;\n break;\n case SourceType.Parent:\n loadReason = `from module ${source.parentId}`;\n break;\n case SourceType.Update:\n loadReason = \"from an HMR update\";\n break;\n }\n throw new Error(\n `Failed to load chunk ${chunkPath} ${loadReason}${\n error ? `: ${error}` : \"\"\n }`,\n error\n ? {\n cause: error,\n }\n : undefined\n );\n }\n}\n\n/**\n * Returns an absolute url to an asset.\n */\nfunction createResolvePathFromModule(\n resolver: (moduleId: string) => Exports\n): (moduleId: string) => string {\n return function resolvePathFromModule(moduleId: string): string {\n const exported = resolver(moduleId);\n return exported?.default ?? exported;\n };\n}\n\nfunction instantiateModule(id: ModuleId, source: SourceInfo): Module {\n const moduleFactory = moduleFactories[id];\n if (typeof moduleFactory !== \"function\") {\n // This can happen if modules incorrectly handle HMR disposes/updates,\n // e.g. when they keep a `setTimeout` around which still executes old code\n // and contains e.g. a `require(\"something\")` call.\n let instantiationReason;\n switch (source.type) {\n case SourceType.Runtime:\n instantiationReason = `as a runtime entry of chunk ${source.chunkPath}`;\n break;\n case SourceType.Parent:\n instantiationReason = `because it was required from module ${source.parentId}`;\n break;\n case SourceType.Update:\n instantiationReason = \"because of an HMR update\";\n break;\n }\n throw new Error(\n `Module ${id} was instantiated ${instantiationReason}, but the module factory is not available. It might have been deleted in an HMR update.`\n );\n }\n\n const hotData = moduleHotData.get(id)!;\n const { hot, hotState } = createModuleHot(id, hotData);\n\n let parents: ModuleId[];\n switch (source.type) {\n case SourceType.Runtime:\n runtimeModules.add(id);\n parents = [];\n break;\n case SourceType.Parent:\n // No need to add this module as a child of the parent module here, this\n // has already been taken care of in `getOrInstantiateModuleFromParent`.\n parents = [source.parentId];\n break;\n case SourceType.Update:\n parents = source.parents || [];\n break;\n }\n const module: Module = {\n exports: {},\n error: undefined,\n loaded: false,\n id,\n parents,\n children: [],\n namespaceObject: undefined,\n hot,\n };\n\n moduleCache[id] = module;\n moduleHotState.set(module, hotState);\n\n // NOTE(alexkirsz) This can fail when the module encounters a runtime error.\n try {\n const sourceInfo: SourceInfo = { type: SourceType.Parent, parentId: id };\n\n runModuleExecutionHooks(module, (refresh) => {\n const r = commonJsRequire.bind(null, module);\n moduleFactory.call(\n module.exports,\n augmentContext({\n a: asyncModule.bind(null, module),\n e: module.exports,\n r: commonJsRequire.bind(null, module),\n t: runtimeRequire,\n f: moduleContext,\n i: esmImport.bind(null, module),\n s: esmExport.bind(null, module, module.exports),\n j: dynamicExport.bind(null, module, module.exports),\n v: exportValue.bind(null, module),\n n: exportNamespace.bind(null, module),\n m: module,\n c: moduleCache,\n M: moduleFactories,\n l: loadChunk.bind(null, sourceInfo),\n w: loadWebAssembly.bind(null, sourceInfo),\n u: loadWebAssemblyModule.bind(null, sourceInfo),\n g: globalThis,\n U: relativeURL,\n k: refresh,\n R: createResolvePathFromModule(r),\n __dirname: module.id.replace(/(^|\\/)\\/+$/, \"\"),\n })\n );\n });\n } catch (error) {\n module.error = error as any;\n throw error;\n }\n\n module.loaded = true;\n if (module.namespaceObject && module.exports !== module.namespaceObject) {\n // in case of a circular dependency: cjs1 -> esm2 -> cjs1\n interopEsm(module.exports, module.namespaceObject);\n }\n\n return module;\n}\n\n/**\n * NOTE(alexkirsz) Webpack has a \"module execution\" interception hook that\n * Next.js' React Refresh runtime hooks into to add module context to the\n * refresh registry.\n */\nfunction runModuleExecutionHooks(\n module: Module,\n executeModule: (ctx: RefreshContext) => void\n) {\n const cleanupReactRefreshIntercept =\n typeof globalThis.$RefreshInterceptModuleExecution$ === \"function\"\n ? globalThis.$RefreshInterceptModuleExecution$(module.id)\n : () => {};\n\n try {\n executeModule({\n register: globalThis.$RefreshReg$,\n signature: globalThis.$RefreshSig$,\n });\n\n if (\"$RefreshHelpers$\" in globalThis) {\n // This pattern can also be used to register the exports of\n // a module with the React Refresh runtime.\n registerExportsAndSetupBoundaryForReactRefresh(\n module,\n globalThis.$RefreshHelpers$\n );\n }\n } catch (e) {\n throw e;\n } finally {\n // Always cleanup the intercept, even if module execution failed.\n cleanupReactRefreshIntercept();\n }\n}\n\n/**\n * Retrieves a module from the cache, or instantiate it if it is not cached.\n */\nconst getOrInstantiateModuleFromParent: GetOrInstantiateModuleFromParent = (\n id,\n sourceModule\n) => {\n if (!sourceModule.hot.active) {\n console.warn(\n `Unexpected import of module ${id} from module ${sourceModule.id}, which was deleted by an HMR update`\n );\n }\n\n const module = moduleCache[id];\n\n if (sourceModule.children.indexOf(id) === -1) {\n sourceModule.children.push(id);\n }\n\n if (module) {\n if (module.parents.indexOf(sourceModule.id) === -1) {\n module.parents.push(sourceModule.id);\n }\n\n return module;\n }\n\n return instantiateModule(id, {\n type: SourceType.Parent,\n parentId: sourceModule.id,\n });\n};\n\n/**\n * This is adapted from https://github.com/vercel/next.js/blob/3466862d9dc9c8bb3131712134d38757b918d1c0/packages/react-refresh-utils/internal/ReactRefreshModule.runtime.ts\n */\nfunction registerExportsAndSetupBoundaryForReactRefresh(\n module: Module,\n helpers: RefreshHelpers\n) {\n const currentExports = module.exports;\n const prevExports = module.hot.data.prevExports ?? null;\n\n helpers.registerExportsForReactRefresh(currentExports, module.id);\n\n // A module can be accepted automatically based on its exports, e.g. when\n // it is a Refresh Boundary.\n if (helpers.isReactRefreshBoundary(currentExports)) {\n // Save the previous exports on update, so we can compare the boundary\n // signatures.\n module.hot.dispose((data) => {\n data.prevExports = currentExports;\n });\n // Unconditionally accept an update to this module, we'll check if it's\n // still a Refresh Boundary later.\n module.hot.accept();\n\n // This field is set when the previous version of this module was a\n // Refresh Boundary, letting us know we need to check for invalidation or\n // enqueue an update.\n if (prevExports !== null) {\n // A boundary can become ineligible if its exports are incompatible\n // with the previous exports.\n //\n // For example, if you add/remove/change exports, we'll want to\n // re-execute the importing modules, and force those components to\n // re-render. Similarly, if you convert a class component to a\n // function, we want to invalidate the boundary.\n if (\n helpers.shouldInvalidateReactRefreshBoundary(\n helpers.getRefreshBoundarySignature(prevExports),\n helpers.getRefreshBoundarySignature(currentExports)\n )\n ) {\n module.hot.invalidate();\n } else {\n helpers.scheduleUpdate();\n }\n }\n } else {\n // Since we just executed the code for the module, it's possible that the\n // new exports made it ineligible for being a boundary.\n // We only care about the case when we were _previously_ a boundary,\n // because we already accepted this update (accidental side effect).\n const isNoLongerABoundary = prevExports !== null;\n if (isNoLongerABoundary) {\n module.hot.invalidate();\n }\n }\n}\n\nfunction formatDependencyChain(dependencyChain: ModuleId[]): string {\n return `Dependency chain: ${dependencyChain.join(\" -> \")}`;\n}\n\nfunction computeOutdatedModules(\n added: Map,\n modified: Map\n): {\n outdatedModules: Set;\n newModuleFactories: Map;\n} {\n const newModuleFactories = new Map();\n\n for (const [moduleId, entry] of added) {\n if (entry != null) {\n newModuleFactories.set(moduleId, _eval(entry));\n }\n }\n\n const outdatedModules = computedInvalidatedModules(modified.keys());\n\n for (const [moduleId, entry] of modified) {\n newModuleFactories.set(moduleId, _eval(entry));\n }\n\n return { outdatedModules, newModuleFactories };\n}\n\nfunction computedInvalidatedModules(\n invalidated: Iterable\n): Set {\n const outdatedModules = new Set();\n\n for (const moduleId of invalidated) {\n const effect = getAffectedModuleEffects(moduleId);\n\n switch (effect.type) {\n case \"unaccepted\":\n throw new UpdateApplyError(\n `cannot apply update: unaccepted module. ${formatDependencyChain(\n effect.dependencyChain\n )}.`,\n effect.dependencyChain\n );\n case \"self-declined\":\n throw new UpdateApplyError(\n `cannot apply update: self-declined module. ${formatDependencyChain(\n effect.dependencyChain\n )}.`,\n effect.dependencyChain\n );\n case \"accepted\":\n for (const outdatedModuleId of effect.outdatedModules) {\n outdatedModules.add(outdatedModuleId);\n }\n break;\n // TODO(alexkirsz) Dependencies: handle dependencies effects.\n }\n }\n\n return outdatedModules;\n}\n\nfunction computeOutdatedSelfAcceptedModules(\n outdatedModules: Iterable\n): { moduleId: ModuleId; errorHandler: true | Function }[] {\n const outdatedSelfAcceptedModules = [];\n for (const moduleId of outdatedModules) {\n const module = moduleCache[moduleId];\n const hotState = moduleHotState.get(module)!;\n if (module && hotState.selfAccepted && !hotState.selfInvalidated) {\n outdatedSelfAcceptedModules.push({\n moduleId,\n errorHandler: hotState.selfAccepted,\n });\n }\n }\n return outdatedSelfAcceptedModules;\n}\n\n/**\n * Adds, deletes, and moves modules between chunks. This must happen before the\n * dispose phase as it needs to know which modules were removed from all chunks,\n * which we can only compute *after* taking care of added and moved modules.\n */\nfunction updateChunksPhase(\n chunksAddedModules: Map>,\n chunksDeletedModules: Map>\n): { disposedModules: Set } {\n for (const [chunkPath, addedModuleIds] of chunksAddedModules) {\n for (const moduleId of addedModuleIds) {\n addModuleToChunk(moduleId, chunkPath);\n }\n }\n\n const disposedModules: Set = new Set();\n for (const [chunkPath, addedModuleIds] of chunksDeletedModules) {\n for (const moduleId of addedModuleIds) {\n if (removeModuleFromChunk(moduleId, chunkPath)) {\n disposedModules.add(moduleId);\n }\n }\n }\n\n return { disposedModules };\n}\n\nfunction disposePhase(\n outdatedModules: Iterable,\n disposedModules: Iterable\n): { outdatedModuleParents: Map> } {\n for (const moduleId of outdatedModules) {\n disposeModule(moduleId, \"replace\");\n }\n\n for (const moduleId of disposedModules) {\n disposeModule(moduleId, \"clear\");\n }\n\n // Removing modules from the module cache is a separate step.\n // We also want to keep track of previous parents of the outdated modules.\n const outdatedModuleParents = new Map();\n for (const moduleId of outdatedModules) {\n const oldModule = moduleCache[moduleId];\n outdatedModuleParents.set(moduleId, oldModule?.parents);\n delete moduleCache[moduleId];\n }\n\n // TODO(alexkirsz) Dependencies: remove outdated dependency from module\n // children.\n\n return { outdatedModuleParents };\n}\n\n/**\n * Disposes of an instance of a module.\n *\n * Returns the persistent hot data that should be kept for the next module\n * instance.\n *\n * NOTE: mode = \"replace\" will not remove modules from the moduleCache.\n * This must be done in a separate step afterwards.\n * This is important because all modules need to be disposed to update the\n * parent/child relationships before they are actually removed from the moduleCache.\n * If this was done in this method, the following disposeModule calls won't find\n * the module from the module id in the cache.\n */\nfunction disposeModule(moduleId: ModuleId, mode: \"clear\" | \"replace\") {\n const module = moduleCache[moduleId];\n if (!module) {\n return;\n }\n\n const hotState = moduleHotState.get(module)!;\n const data = {};\n\n // Run the `hot.dispose` handler, if any, passing in the persistent\n // `hot.data` object.\n for (const disposeHandler of hotState.disposeHandlers) {\n disposeHandler(data);\n }\n\n // This used to warn in `getOrInstantiateModuleFromParent` when a disposed\n // module is still importing other modules.\n module.hot.active = false;\n\n moduleHotState.delete(module);\n\n // TODO(alexkirsz) Dependencies: delete the module from outdated deps.\n\n // Remove the disposed module from its children's parent list.\n // It will be added back once the module re-instantiates and imports its\n // children again.\n for (const childId of module.children) {\n const child = moduleCache[childId];\n if (!child) {\n continue;\n }\n\n const idx = child.parents.indexOf(module.id);\n if (idx >= 0) {\n child.parents.splice(idx, 1);\n }\n }\n\n switch (mode) {\n case \"clear\":\n delete moduleCache[module.id];\n moduleHotData.delete(module.id);\n break;\n case \"replace\":\n moduleHotData.set(module.id, data);\n break;\n default:\n invariant(mode, (mode) => `invalid mode: ${mode}`);\n }\n}\n\nfunction applyPhase(\n outdatedSelfAcceptedModules: {\n moduleId: ModuleId;\n errorHandler: true | Function;\n }[],\n newModuleFactories: Map,\n outdatedModuleParents: Map>,\n reportError: (err: any) => void\n) {\n // Update module factories.\n for (const [moduleId, factory] of newModuleFactories.entries()) {\n moduleFactories[moduleId] = factory;\n }\n\n // TODO(alexkirsz) Run new runtime entries here.\n\n // TODO(alexkirsz) Dependencies: call accept handlers for outdated deps.\n\n // Re-instantiate all outdated self-accepted modules.\n for (const { moduleId, errorHandler } of outdatedSelfAcceptedModules) {\n try {\n instantiateModule(moduleId, {\n type: SourceType.Update,\n parents: outdatedModuleParents.get(moduleId),\n });\n } catch (err) {\n if (typeof errorHandler === \"function\") {\n try {\n errorHandler(err, { moduleId, module: moduleCache[moduleId] });\n } catch (err2) {\n reportError(err2);\n reportError(err);\n }\n } else {\n reportError(err);\n }\n }\n }\n}\n\n/**\n * Utility function to ensure all variants of an enum are handled.\n */\nfunction invariant(never: never, computeMessage: (arg: any) => string): never {\n throw new Error(`Invariant: ${computeMessage(never)}`);\n}\n\nfunction applyUpdate(update: PartialUpdate) {\n switch (update.type) {\n case \"ChunkListUpdate\":\n applyChunkListUpdate(update);\n break;\n default:\n invariant(update, (update) => `Unknown update type: ${update.type}`);\n }\n}\n\nfunction applyChunkListUpdate(update: ChunkListUpdate) {\n if (update.merged != null) {\n for (const merged of update.merged) {\n switch (merged.type) {\n case \"EcmascriptMergedUpdate\":\n applyEcmascriptMergedUpdate(merged);\n break;\n default:\n invariant(merged, (merged) => `Unknown merged type: ${merged.type}`);\n }\n }\n }\n\n if (update.chunks != null) {\n for (const [chunkPath, chunkUpdate] of Object.entries(update.chunks)) {\n switch (chunkUpdate.type) {\n case \"added\":\n BACKEND.loadChunk(chunkPath, { type: SourceType.Update });\n break;\n case \"total\":\n BACKEND.reloadChunk?.(chunkPath);\n break;\n case \"deleted\":\n BACKEND.unloadChunk?.(chunkPath);\n break;\n case \"partial\":\n invariant(\n chunkUpdate.instruction,\n (instruction) =>\n `Unknown partial instruction: ${JSON.stringify(instruction)}.`\n );\n default:\n invariant(\n chunkUpdate,\n (chunkUpdate) => `Unknown chunk update type: ${chunkUpdate.type}`\n );\n }\n }\n }\n}\n\nfunction applyEcmascriptMergedUpdate(update: EcmascriptMergedUpdate) {\n const { entries = {}, chunks = {} } = update;\n const { added, modified, chunksAdded, chunksDeleted } = computeChangedModules(\n entries,\n chunks\n );\n const { outdatedModules, newModuleFactories } = computeOutdatedModules(\n added,\n modified\n );\n const { disposedModules } = updateChunksPhase(chunksAdded, chunksDeleted);\n\n applyInternal(outdatedModules, disposedModules, newModuleFactories);\n}\n\nfunction applyInvalidatedModules(outdatedModules: Set) {\n if (queuedInvalidatedModules.size > 0) {\n computedInvalidatedModules(queuedInvalidatedModules).forEach((moduleId) => {\n outdatedModules.add(moduleId);\n });\n\n queuedInvalidatedModules.clear();\n }\n\n return outdatedModules;\n}\n\nfunction applyInternal(\n outdatedModules: Set,\n disposedModules: Iterable,\n newModuleFactories: Map\n) {\n outdatedModules = applyInvalidatedModules(outdatedModules);\n\n const outdatedSelfAcceptedModules =\n computeOutdatedSelfAcceptedModules(outdatedModules);\n\n const { outdatedModuleParents } = disposePhase(\n outdatedModules,\n disposedModules\n );\n\n // we want to continue on error and only throw the error after we tried applying all updates\n let error: any;\n\n function reportError(err: any) {\n if (!error) error = err;\n }\n\n applyPhase(\n outdatedSelfAcceptedModules,\n newModuleFactories,\n outdatedModuleParents,\n reportError\n );\n\n if (error) {\n throw error;\n }\n\n if (queuedInvalidatedModules.size > 0) {\n applyInternal(new Set(), [], new Map());\n }\n}\n\nfunction computeChangedModules(\n entries: Record,\n updates: Record\n): {\n added: Map;\n modified: Map;\n deleted: Set;\n chunksAdded: Map>;\n chunksDeleted: Map>;\n} {\n const chunksAdded = new Map();\n const chunksDeleted = new Map();\n const added: Map = new Map();\n const modified = new Map();\n const deleted: Set = new Set();\n\n for (const [chunkPath, mergedChunkUpdate] of Object.entries(updates)) {\n switch (mergedChunkUpdate.type) {\n case \"added\": {\n const updateAdded = new Set(mergedChunkUpdate.modules);\n for (const moduleId of updateAdded) {\n added.set(moduleId, entries[moduleId]);\n }\n chunksAdded.set(chunkPath, updateAdded);\n break;\n }\n case \"deleted\": {\n // We could also use `mergedChunkUpdate.modules` here.\n const updateDeleted = new Set(chunkModulesMap.get(chunkPath));\n for (const moduleId of updateDeleted) {\n deleted.add(moduleId);\n }\n chunksDeleted.set(chunkPath, updateDeleted);\n break;\n }\n case \"partial\": {\n const updateAdded = new Set(mergedChunkUpdate.added);\n const updateDeleted = new Set(mergedChunkUpdate.deleted);\n for (const moduleId of updateAdded) {\n added.set(moduleId, entries[moduleId]);\n }\n for (const moduleId of updateDeleted) {\n deleted.add(moduleId);\n }\n chunksAdded.set(chunkPath, updateAdded);\n chunksDeleted.set(chunkPath, updateDeleted);\n break;\n }\n default:\n invariant(\n mergedChunkUpdate,\n (mergedChunkUpdate) =>\n `Unknown merged chunk update type: ${mergedChunkUpdate.type}`\n );\n }\n }\n\n // If a module was added from one chunk and deleted from another in the same update,\n // consider it to be modified, as it means the module was moved from one chunk to another\n // AND has new code in a single update.\n for (const moduleId of added.keys()) {\n if (deleted.has(moduleId)) {\n added.delete(moduleId);\n deleted.delete(moduleId);\n }\n }\n\n for (const [moduleId, entry] of Object.entries(entries)) {\n // Modules that haven't been added to any chunk but have new code are considered\n // to be modified.\n // This needs to be under the previous loop, as we need it to get rid of modules\n // that were added and deleted in the same update.\n if (!added.has(moduleId)) {\n modified.set(moduleId, entry);\n }\n }\n\n return { added, deleted, modified, chunksAdded, chunksDeleted };\n}\n\ntype ModuleEffect =\n | {\n type: \"unaccepted\";\n dependencyChain: ModuleId[];\n }\n | {\n type: \"self-declined\";\n dependencyChain: ModuleId[];\n moduleId: ModuleId;\n }\n | {\n type: \"accepted\";\n moduleId: ModuleId;\n outdatedModules: Set;\n };\n\nfunction getAffectedModuleEffects(moduleId: ModuleId): ModuleEffect {\n const outdatedModules: Set = new Set();\n\n type QueueItem = { moduleId?: ModuleId; dependencyChain: ModuleId[] };\n\n const queue: QueueItem[] = [\n {\n moduleId,\n dependencyChain: [],\n },\n ];\n\n let nextItem;\n while ((nextItem = queue.shift())) {\n const { moduleId, dependencyChain } = nextItem;\n\n if (moduleId != null) {\n outdatedModules.add(moduleId);\n }\n\n // We've arrived at the runtime of the chunk, which means that nothing\n // else above can accept this update.\n if (moduleId === undefined) {\n return {\n type: \"unaccepted\",\n dependencyChain,\n };\n }\n\n const module = moduleCache[moduleId];\n const hotState = moduleHotState.get(module)!;\n\n if (\n // The module is not in the cache. Since this is a \"modified\" update,\n // it means that the module was never instantiated before.\n !module || // The module accepted itself without invalidating globalThis.\n // TODO is that right?\n (hotState.selfAccepted && !hotState.selfInvalidated)\n ) {\n continue;\n }\n\n if (hotState.selfDeclined) {\n return {\n type: \"self-declined\",\n dependencyChain,\n moduleId,\n };\n }\n\n if (runtimeModules.has(moduleId)) {\n queue.push({\n moduleId: undefined,\n dependencyChain: [...dependencyChain, moduleId],\n });\n continue;\n }\n\n for (const parentId of module.parents) {\n const parent = moduleCache[parentId];\n\n if (!parent) {\n // TODO(alexkirsz) Is this even possible?\n continue;\n }\n\n // TODO(alexkirsz) Dependencies: check accepted and declined\n // dependencies here.\n\n queue.push({\n moduleId: parentId,\n dependencyChain: [...dependencyChain, moduleId],\n });\n }\n }\n\n return {\n type: \"accepted\",\n moduleId,\n outdatedModules,\n };\n}\n\nfunction handleApply(chunkListPath: ChunkPath, update: ServerMessage) {\n switch (update.type) {\n case \"partial\": {\n // This indicates that the update is can be applied to the current state of the application.\n applyUpdate(update.instruction);\n break;\n }\n case \"restart\": {\n // This indicates that there is no way to apply the update to the\n // current state of the application, and that the application must be\n // restarted.\n BACKEND.restart();\n break;\n }\n case \"notFound\": {\n // This indicates that the chunk list no longer exists: either the dynamic import which created it was removed,\n // or the page itself was deleted.\n // If it is a dynamic import, we simply discard all modules that the chunk has exclusive access to.\n // If it is a runtime chunk list, we restart the application.\n if (runtimeChunkLists.has(chunkListPath)) {\n BACKEND.restart();\n } else {\n disposeChunkList(chunkListPath);\n }\n break;\n }\n default:\n throw new Error(`Unknown update type: ${update.type}`);\n }\n}\n\nfunction createModuleHot(\n moduleId: ModuleId,\n hotData: HotData\n): { hot: Hot; hotState: HotState } {\n const hotState: HotState = {\n selfAccepted: false,\n selfDeclined: false,\n selfInvalidated: false,\n disposeHandlers: [],\n };\n\n const hot: Hot = {\n // TODO(alexkirsz) This is not defined in the HMR API. It was used to\n // decide whether to warn whenever an HMR-disposed module required other\n // modules. We might want to remove it.\n active: true,\n\n data: hotData ?? {},\n\n // TODO(alexkirsz) Support full (dep, callback, errorHandler) form.\n accept: (\n modules?: string | string[] | AcceptErrorHandler,\n _callback?: AcceptCallback,\n _errorHandler?: AcceptErrorHandler\n ) => {\n if (modules === undefined) {\n hotState.selfAccepted = true;\n } else if (typeof modules === \"function\") {\n hotState.selfAccepted = modules;\n } else {\n throw new Error(\"unsupported `accept` signature\");\n }\n },\n\n decline: (dep) => {\n if (dep === undefined) {\n hotState.selfDeclined = true;\n } else {\n throw new Error(\"unsupported `decline` signature\");\n }\n },\n\n dispose: (callback) => {\n hotState.disposeHandlers.push(callback);\n },\n\n addDisposeHandler: (callback) => {\n hotState.disposeHandlers.push(callback);\n },\n\n removeDisposeHandler: (callback) => {\n const idx = hotState.disposeHandlers.indexOf(callback);\n if (idx >= 0) {\n hotState.disposeHandlers.splice(idx, 1);\n }\n },\n\n invalidate: () => {\n hotState.selfInvalidated = true;\n queuedInvalidatedModules.add(moduleId);\n },\n\n // NOTE(alexkirsz) This is part of the management API, which we don't\n // implement, but the Next.js React Refresh runtime uses this to decide\n // whether to schedule an update.\n status: () => \"idle\",\n\n // NOTE(alexkirsz) Since we always return \"idle\" for now, these are no-ops.\n addStatusHandler: (_handler) => {},\n removeStatusHandler: (_handler) => {},\n\n // NOTE(jridgewell) Check returns the list of updated modules, but we don't\n // want the webpack code paths to ever update (the turbopack paths handle\n // this already).\n check: () => Promise.resolve(null),\n };\n\n return { hot, hotState };\n}\n\n/**\n * Adds a module to a chunk.\n */\nfunction addModuleToChunk(moduleId: ModuleId, chunkPath: ChunkPath) {\n let moduleChunks = moduleChunksMap.get(moduleId);\n if (!moduleChunks) {\n moduleChunks = new Set([chunkPath]);\n moduleChunksMap.set(moduleId, moduleChunks);\n } else {\n moduleChunks.add(chunkPath);\n }\n\n let chunkModules = chunkModulesMap.get(chunkPath);\n if (!chunkModules) {\n chunkModules = new Set([moduleId]);\n chunkModulesMap.set(chunkPath, chunkModules);\n } else {\n chunkModules.add(moduleId);\n }\n}\n\n/**\n * Returns the first chunk that included a module.\n * This is used by the Node.js backend, hence why it's marked as unused in this\n * file.\n */\nfunction getFirstModuleChunk(moduleId: ModuleId) {\n const moduleChunkPaths = moduleChunksMap.get(moduleId);\n if (moduleChunkPaths == null) {\n return null;\n }\n\n return moduleChunkPaths.values().next().value;\n}\n\n/**\n * Removes a module from a chunk.\n * Returns `true` if there are no remaining chunks including this module.\n */\nfunction removeModuleFromChunk(\n moduleId: ModuleId,\n chunkPath: ChunkPath\n): boolean {\n const moduleChunks = moduleChunksMap.get(moduleId)!;\n moduleChunks.delete(chunkPath);\n\n const chunkModules = chunkModulesMap.get(chunkPath)!;\n chunkModules.delete(moduleId);\n\n const noRemainingModules = chunkModules.size === 0;\n if (noRemainingModules) {\n chunkModulesMap.delete(chunkPath);\n }\n\n const noRemainingChunks = moduleChunks.size === 0;\n if (noRemainingChunks) {\n moduleChunksMap.delete(moduleId);\n }\n\n return noRemainingChunks;\n}\n\n/**\n * Disposes of a chunk list and its corresponding exclusive chunks.\n */\nfunction disposeChunkList(chunkListPath: ChunkPath): boolean {\n const chunkPaths = chunkListChunksMap.get(chunkListPath);\n if (chunkPaths == null) {\n return false;\n }\n chunkListChunksMap.delete(chunkListPath);\n\n for (const chunkPath of chunkPaths) {\n const chunkChunkLists = chunkChunkListsMap.get(chunkPath)!;\n chunkChunkLists.delete(chunkListPath);\n\n if (chunkChunkLists.size === 0) {\n chunkChunkListsMap.delete(chunkPath);\n disposeChunk(chunkPath);\n }\n }\n\n // We must also dispose of the chunk list's chunk itself to ensure it may\n // be reloaded properly in the future.\n BACKEND.unloadChunk?.(chunkListPath);\n\n return true;\n}\n\n/**\n * Disposes of a chunk and its corresponding exclusive modules.\n *\n * @returns Whether the chunk was disposed of.\n */\nfunction disposeChunk(chunkPath: ChunkPath): boolean {\n // This should happen whether the chunk has any modules in it or not.\n // For instance, CSS chunks have no modules in them, but they still need to be unloaded.\n BACKEND.unloadChunk?.(chunkPath);\n\n const chunkModules = chunkModulesMap.get(chunkPath);\n if (chunkModules == null) {\n return false;\n }\n chunkModules.delete(chunkPath);\n\n for (const moduleId of chunkModules) {\n const moduleChunks = moduleChunksMap.get(moduleId)!;\n moduleChunks.delete(chunkPath);\n\n const noRemainingChunks = moduleChunks.size === 0;\n if (noRemainingChunks) {\n moduleChunksMap.delete(moduleId);\n disposeModule(moduleId, \"clear\");\n availableModules.delete(moduleId);\n }\n }\n\n return true;\n}\n\n/**\n * Instantiates a runtime module.\n */\nfunction instantiateRuntimeModule(\n moduleId: ModuleId,\n chunkPath: ChunkPath\n): Module {\n return instantiateModule(moduleId, { type: SourceType.Runtime, chunkPath });\n}\n\n/**\n * Gets or instantiates a runtime module.\n */\nfunction getOrInstantiateRuntimeModule(\n moduleId: ModuleId,\n chunkPath: ChunkPath\n): Module {\n const module = moduleCache[moduleId];\n if (module) {\n if (module.error) {\n throw module.error;\n }\n return module;\n }\n\n return instantiateModule(moduleId, { type: SourceType.Runtime, chunkPath });\n}\n\n/**\n * Returns the URL relative to the origin where a chunk can be fetched from.\n */\nfunction getChunkRelativeUrl(chunkPath: ChunkPath): string {\n return `${CHUNK_BASE_PATH}${chunkPath\n .split(\"/\")\n .map((p) => encodeURIComponent(p))\n .join(\"/\")}`;\n}\n\n/**\n * Subscribes to chunk list updates from the update server and applies them.\n */\nfunction registerChunkList(\n chunkUpdateProvider: ChunkUpdateProvider,\n chunkList: ChunkList\n) {\n chunkUpdateProvider.push([\n chunkList.path,\n handleApply.bind(null, chunkList.path),\n ]);\n\n // Adding chunks to chunk lists and vice versa.\n const chunks = new Set(chunkList.chunks.map(getChunkPath));\n chunkListChunksMap.set(chunkList.path, chunks);\n for (const chunkPath of chunks) {\n let chunkChunkLists = chunkChunkListsMap.get(chunkPath);\n if (!chunkChunkLists) {\n chunkChunkLists = new Set([chunkList.path]);\n chunkChunkListsMap.set(chunkPath, chunkChunkLists);\n } else {\n chunkChunkLists.add(chunkList.path);\n }\n }\n\n if (chunkList.source === \"entry\") {\n markChunkListAsRuntime(chunkList.path);\n }\n}\n\n/**\n * Marks a chunk list as a runtime chunk list. There can be more than one\n * runtime chunk list. For instance, integration tests can have multiple chunk\n * groups loaded at runtime, each with its own chunk list.\n */\nfunction markChunkListAsRuntime(chunkListPath: ChunkPath) {\n runtimeChunkLists.add(chunkListPath);\n}\n\nfunction registerChunk([\n chunkPath,\n chunkModules,\n runtimeParams,\n]: ChunkRegistration) {\n for (const [moduleId, moduleFactory] of Object.entries(chunkModules)) {\n if (!moduleFactories[moduleId]) {\n moduleFactories[moduleId] = moduleFactory;\n }\n addModuleToChunk(moduleId, chunkPath);\n }\n\n return BACKEND.registerChunk(chunkPath, runtimeParams);\n}\n\nglobalThis.TURBOPACK_CHUNK_UPDATE_LISTENERS ??= [];\n\nconst chunkListsToRegister = globalThis.TURBOPACK_CHUNK_LISTS;\nif (Array.isArray(chunkListsToRegister)) {\n for (const chunkList of chunkListsToRegister) {\n registerChunkList(globalThis.TURBOPACK_CHUNK_UPDATE_LISTENERS, chunkList);\n }\n}\n\nglobalThis.TURBOPACK_CHUNK_LISTS = {\n push: (chunkList) => {\n registerChunkList(globalThis.TURBOPACK_CHUNK_UPDATE_LISTENERS!, chunkList);\n },\n} satisfies ChunkListProvider;\n"],"names":[],"mappings":"AAAA;;;;;;CAMC,GAED,uDAAuD,GAEvD,yDAAyD;AACzD,uCAAuC;AACvC,wCAAwC;AACxC,0CAA0C;AAE1C,yEAAyE;AACzE,4EAA4E;AAC5E,wDAAwD;;UAiDnD;IACH;;;GAGC;IAED;;GAEC;IAED;;;GAGC;GAbE,eAAA;AAwCL,MAAM,yBAAyB;IAC7B,OAAO,mBAAmB;IAE1B,gBAA0B;IAE1B,YAAY,OAAe,EAAE,eAAyB,CAAE;QACtD,KAAK,CAAC;QACN,IAAI,CAAC,eAAe,GAAG;IACzB;AACF;AAEA,MAAM,kBAAmC,OAAO,MAAM,CAAC;AACvD,MAAM,cAA2B,OAAO,MAAM,CAAC;AAC/C;;;CAGC,GACD,MAAM,gBAAwC,IAAI;AAClD;;CAEC,GACD,MAAM,iBAAwC,IAAI;AAClD;;CAEC,GACD,MAAM,2BAA0C,IAAI;AACpD;;CAEC,GACD,MAAM,iBAAgC,IAAI;AAC1C;;;;;;CAMC,GACD,MAAM,kBAAiD,IAAI;AAC3D;;CAEC,GACD,MAAM,kBAAiD,IAAI;AAC3D;;;;CAIC,GACD,MAAM,oBAAoC,IAAI;AAC9C;;CAEC,GACD,MAAM,qBAAqD,IAAI;AAC/D;;CAEC,GACD,MAAM,qBAAqD,IAAI;AAE/D,MAAM,mBAAuD,IAAI;AAEjE,MAAM,wBAA6D,IAAI;AAEvE,eAAe,UACb,MAAkB,EAClB,SAAoB;IAEpB,IAAI,OAAO,cAAc,UAAU;QACjC,OAAO,cAAc,QAAQ;IAC/B;IAEA,MAAM,eAAe,UAAU,QAAQ,IAAI,EAAE;IAC7C,MAAM,kBAAkB,aAAa,GAAG,CAAC,CAAC;QACxC,IAAI,eAAe,CAAC,SAAS,EAAE,OAAO;QACtC,OAAO,iBAAiB,GAAG,CAAC;IAC9B;IACA,IAAI,gBAAgB,MAAM,GAAG,KAAK,gBAAgB,KAAK,CAAC,CAAC,IAAM,IAAI;QACjE,uFAAuF;QACvF,OAAO,QAAQ,GAAG,CAAC;IACrB;IAEA,MAAM,2BAA2B,UAAU,YAAY,IAAI,EAAE;IAC7D,MAAM,uBAAuB,yBAC1B,GAAG,CAAC,CAAC;QACJ,yCAAyC;QACzC,8CAA8C;QAC9C,OAAO,sBAAsB,GAAG,CAAC;IACnC,GACC,MAAM,CAAC,CAAC,IAAM;IAEjB,IAAI;IACJ,IAAI,qBAAqB,MAAM,GAAG,GAAG;QACnC,oDAAoD;QAEpD,IAAI,qBAAqB,MAAM,IAAI,yBAAyB,MAAM,EAAE;YAClE,+FAA+F;YAC/F,OAAO,QAAQ,GAAG,CAAC;QACrB;QAEA,MAAM,qBAAqC,IAAI;QAC/C,KAAK,MAAM,eAAe,yBAA0B;YAClD,IAAI,CAAC,sBAAsB,GAAG,CAAC,cAAc;gBAC3C,mBAAmB,GAAG,CAAC;YACzB;QACF;QAEA,KAAK,MAAM,qBAAqB,mBAAoB;YAClD,MAAM,UAAU,cAAc,QAAQ;YAEtC,sBAAsB,GAAG,CAAC,mBAAmB;YAE7C,qBAAqB,IAAI,CAAC;QAC5B;QAEA,UAAU,QAAQ,GAAG,CAAC;IACxB,OAAO;QACL,UAAU,cAAc,QAAQ,UAAU,IAAI;QAE9C,wFAAwF;QACxF,KAAK,MAAM,uBAAuB,yBAA0B;YAC1D,IAAI,CAAC,sBAAsB,GAAG,CAAC,sBAAsB;gBACnD,sBAAsB,GAAG,CAAC,qBAAqB;YACjD;QACF;IACF;IAEA,KAAK,MAAM,YAAY,aAAc;QACnC,IAAI,CAAC,iBAAiB,GAAG,CAAC,WAAW;YACnC,qIAAqI;YACrI,yGAAyG;YACzG,iBAAiB,GAAG,CAAC,UAAU;QACjC;IACF;IAEA,OAAO;AACT;AAEA,eAAe,cACb,MAAkB,EAClB,SAAoB;IAEpB,IAAI;QACF,MAAM,QAAQ,SAAS,CAAC,WAAW;IACrC,EAAE,OAAO,OAAO;QACd,IAAI;QACJ,OAAQ,OAAO,IAAI;YACjB;gBACE,aAAa,CAAC,iCAAiC,EAAE,OAAO,SAAS,CAAC,CAAC;gBACnE;YACF;gBACE,aAAa,CAAC,YAAY,EAAE,OAAO,QAAQ,CAAC,CAAC;gBAC7C;YACF;gBACE,aAAa;gBACb;QACJ;QACA,MAAM,IAAI,MACR,CAAC,qBAAqB,EAAE,UAAU,CAAC,EAAE,WAAW,EAC9C,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC,GAAG,GACxB,CAAC,EACF,QACI;YACE,OAAO;QACT,IACA;IAER;AACF;AAEA;;CAEC,GACD,SAAS,4BACP,QAAuC;IAEvC,OAAO,SAAS,sBAAsB,QAAgB;QACpD,MAAM,WAAW,SAAS;QAC1B,OAAO,UAAU,WAAW;IAC9B;AACF;AAEA,SAAS,kBAAkB,EAAY,EAAE,MAAkB;IACzD,MAAM,gBAAgB,eAAe,CAAC,GAAG;IACzC,IAAI,OAAO,kBAAkB,YAAY;QACvC,sEAAsE;QACtE,0EAA0E;QAC1E,mDAAmD;QACnD,IAAI;QACJ,OAAQ,OAAO,IAAI;YACjB;gBACE,sBAAsB,CAAC,4BAA4B,EAAE,OAAO,SAAS,CAAC,CAAC;gBACvE;YACF;gBACE,sBAAsB,CAAC,oCAAoC,EAAE,OAAO,QAAQ,CAAC,CAAC;gBAC9E;YACF;gBACE,sBAAsB;gBACtB;QACJ;QACA,MAAM,IAAI,MACR,CAAC,OAAO,EAAE,GAAG,kBAAkB,EAAE,oBAAoB,uFAAuF,CAAC;IAEjJ;IAEA,MAAM,UAAU,cAAc,GAAG,CAAC;IAClC,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,gBAAgB,IAAI;IAE9C,IAAI;IACJ,OAAQ,OAAO,IAAI;QACjB;YACE,eAAe,GAAG,CAAC;YACnB,UAAU,EAAE;YACZ;QACF;YACE,wEAAwE;YACxE,wEAAwE;YACxE,UAAU;gBAAC,OAAO,QAAQ;aAAC;YAC3B;QACF;YACE,UAAU,OAAO,OAAO,IAAI,EAAE;YAC9B;IACJ;IACA,MAAM,SAAiB;QACrB,SAAS,CAAC;QACV,OAAO;QACP,QAAQ;QACR;QACA;QACA,UAAU,EAAE;QACZ,iBAAiB;QACjB;IACF;IAEA,WAAW,CAAC,GAAG,GAAG;IAClB,eAAe,GAAG,CAAC,QAAQ;IAE3B,4EAA4E;IAC5E,IAAI;QACF,MAAM,aAAyB;YAAE,IAAI;YAAqB,UAAU;QAAG;QAEvE,wBAAwB,QAAQ,CAAC;YAC/B,MAAM,IAAI,gBAAgB,IAAI,CAAC,MAAM;YACrC,cAAc,IAAI,CAChB,OAAO,OAAO,EACd,eAAe;gBACb,GAAG,YAAY,IAAI,CAAC,MAAM;gBAC1B,GAAG,OAAO,OAAO;gBACjB,GAAG,gBAAgB,IAAI,CAAC,MAAM;gBAC9B,GAAG;gBACH,GAAG;gBACH,GAAG,UAAU,IAAI,CAAC,MAAM;gBACxB,GAAG,UAAU,IAAI,CAAC,MAAM,QAAQ,OAAO,OAAO;gBAC9C,GAAG,cAAc,IAAI,CAAC,MAAM,QAAQ,OAAO,OAAO;gBAClD,GAAG,YAAY,IAAI,CAAC,MAAM;gBAC1B,GAAG,gBAAgB,IAAI,CAAC,MAAM;gBAC9B,GAAG;gBACH,GAAG;gBACH,GAAG;gBACH,GAAG,UAAU,IAAI,CAAC,MAAM;gBACxB,GAAG,gBAAgB,IAAI,CAAC,MAAM;gBAC9B,GAAG,sBAAsB,IAAI,CAAC,MAAM;gBACpC,GAAG;gBACH,GAAG;gBACH,GAAG;gBACH,GAAG,4BAA4B;gBAC/B,WAAW,OAAO,EAAE,CAAC,OAAO,CAAC,cAAc;YAC7C;QAEJ;IACF,EAAE,OAAO,OAAO;QACd,OAAO,KAAK,GAAG;QACf,MAAM;IACR;IAEA,OAAO,MAAM,GAAG;IAChB,IAAI,OAAO,eAAe,IAAI,OAAO,OAAO,KAAK,OAAO,eAAe,EAAE;QACvE,yDAAyD;QACzD,WAAW,OAAO,OAAO,EAAE,OAAO,eAAe;IACnD;IAEA,OAAO;AACT;AAEA;;;;CAIC,GACD,SAAS,wBACP,MAAc,EACd,aAA4C;IAE5C,MAAM,+BACJ,OAAO,WAAW,iCAAiC,KAAK,aACpD,WAAW,iCAAiC,CAAC,OAAO,EAAE,IACtD,KAAO;IAEb,IAAI;QACF,cAAc;YACZ,UAAU,WAAW,YAAY;YACjC,WAAW,WAAW,YAAY;QACpC;QAEA,IAAI,sBAAsB,YAAY;YACpC,2DAA2D;YAC3D,2CAA2C;YAC3C,+CACE,QACA,WAAW,gBAAgB;QAE/B;IACF,EAAE,OAAO,GAAG;QACV,MAAM;IACR,SAAU;QACR,iEAAiE;QACjE;IACF;AACF;AAEA;;CAEC,GACD,MAAM,mCAAqE,CACzE,IACA;IAEA,IAAI,CAAC,aAAa,GAAG,CAAC,MAAM,EAAE;QAC5B,QAAQ,IAAI,CACV,CAAC,4BAA4B,EAAE,GAAG,aAAa,EAAE,aAAa,EAAE,CAAC,oCAAoC,CAAC;IAE1G;IAEA,MAAM,SAAS,WAAW,CAAC,GAAG;IAE9B,IAAI,aAAa,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG;QAC5C,aAAa,QAAQ,CAAC,IAAI,CAAC;IAC7B;IAEA,IAAI,QAAQ;QACV,IAAI,OAAO,OAAO,CAAC,OAAO,CAAC,aAAa,EAAE,MAAM,CAAC,GAAG;YAClD,OAAO,OAAO,CAAC,IAAI,CAAC,aAAa,EAAE;QACrC;QAEA,OAAO;IACT;IAEA,OAAO,kBAAkB,IAAI;QAC3B,IAAI;QACJ,UAAU,aAAa,EAAE;IAC3B;AACF;AAEA;;CAEC,GACD,SAAS,+CACP,MAAc,EACd,OAAuB;IAEvB,MAAM,iBAAiB,OAAO,OAAO;IACrC,MAAM,cAAc,OAAO,GAAG,CAAC,IAAI,CAAC,WAAW,IAAI;IAEnD,QAAQ,8BAA8B,CAAC,gBAAgB,OAAO,EAAE;IAEhE,yEAAyE;IACzE,4BAA4B;IAC5B,IAAI,QAAQ,sBAAsB,CAAC,iBAAiB;QAClD,sEAAsE;QACtE,cAAc;QACd,OAAO,GAAG,CAAC,OAAO,CAAC,CAAC;YAClB,KAAK,WAAW,GAAG;QACrB;QACA,uEAAuE;QACvE,kCAAkC;QAClC,OAAO,GAAG,CAAC,MAAM;QAEjB,mEAAmE;QACnE,yEAAyE;QACzE,qBAAqB;QACrB,IAAI,gBAAgB,MAAM;YACxB,mEAAmE;YACnE,6BAA6B;YAC7B,EAAE;YACF,+DAA+D;YAC/D,kEAAkE;YAClE,8DAA8D;YAC9D,gDAAgD;YAChD,IACE,QAAQ,oCAAoC,CAC1C,QAAQ,2BAA2B,CAAC,cACpC,QAAQ,2BAA2B,CAAC,kBAEtC;gBACA,OAAO,GAAG,CAAC,UAAU;YACvB,OAAO;gBACL,QAAQ,cAAc;YACxB;QACF;IACF,OAAO;QACL,yEAAyE;QACzE,uDAAuD;QACvD,oEAAoE;QACpE,oEAAoE;QACpE,MAAM,sBAAsB,gBAAgB;QAC5C,IAAI,qBAAqB;YACvB,OAAO,GAAG,CAAC,UAAU;QACvB;IACF;AACF;AAEA,SAAS,sBAAsB,eAA2B;IACxD,OAAO,CAAC,kBAAkB,EAAE,gBAAgB,IAAI,CAAC,QAAQ,CAAC;AAC5D;AAEA,SAAS,uBACP,KAAuD,EACvD,QAA8C;IAK9C,MAAM,qBAAqB,IAAI;IAE/B,KAAK,MAAM,CAAC,UAAU,MAAM,IAAI,MAAO;QACrC,IAAI,SAAS,MAAM;YACjB,mBAAmB,GAAG,CAAC,UAAU,MAAM;QACzC;IACF;IAEA,MAAM,kBAAkB,2BAA2B,SAAS,IAAI;IAEhE,KAAK,MAAM,CAAC,UAAU,MAAM,IAAI,SAAU;QACxC,mBAAmB,GAAG,CAAC,UAAU,MAAM;IACzC;IAEA,OAAO;QAAE;QAAiB;IAAmB;AAC/C;AAEA,SAAS,2BACP,WAA+B;IAE/B,MAAM,kBAAkB,IAAI;IAE5B,KAAK,MAAM,YAAY,YAAa;QAClC,MAAM,SAAS,yBAAyB;QAExC,OAAQ,OAAO,IAAI;YACjB,KAAK;gBACH,MAAM,IAAI,iBACR,CAAC,wCAAwC,EAAE,sBACzC,OAAO,eAAe,EACtB,CAAC,CAAC,EACJ,OAAO,eAAe;YAE1B,KAAK;gBACH,MAAM,IAAI,iBACR,CAAC,2CAA2C,EAAE,sBAC5C,OAAO,eAAe,EACtB,CAAC,CAAC,EACJ,OAAO,eAAe;YAE1B,KAAK;gBACH,KAAK,MAAM,oBAAoB,OAAO,eAAe,CAAE;oBACrD,gBAAgB,GAAG,CAAC;gBACtB;gBACA;QAEJ;IACF;IAEA,OAAO;AACT;AAEA,SAAS,mCACP,eAAmC;IAEnC,MAAM,8BAA8B,EAAE;IACtC,KAAK,MAAM,YAAY,gBAAiB;QACtC,MAAM,SAAS,WAAW,CAAC,SAAS;QACpC,MAAM,WAAW,eAAe,GAAG,CAAC;QACpC,IAAI,UAAU,SAAS,YAAY,IAAI,CAAC,SAAS,eAAe,EAAE;YAChE,4BAA4B,IAAI,CAAC;gBAC/B;gBACA,cAAc,SAAS,YAAY;YACrC;QACF;IACF;IACA,OAAO;AACT;AAEA;;;;CAIC,GACD,SAAS,kBACP,kBAAiD,EACjD,oBAAmD;IAEnD,KAAK,MAAM,CAAC,WAAW,eAAe,IAAI,mBAAoB;QAC5D,KAAK,MAAM,YAAY,eAAgB;YACrC,iBAAiB,UAAU;QAC7B;IACF;IAEA,MAAM,kBAAiC,IAAI;IAC3C,KAAK,MAAM,CAAC,WAAW,eAAe,IAAI,qBAAsB;QAC9D,KAAK,MAAM,YAAY,eAAgB;YACrC,IAAI,sBAAsB,UAAU,YAAY;gBAC9C,gBAAgB,GAAG,CAAC;YACtB;QACF;IACF;IAEA,OAAO;QAAE;IAAgB;AAC3B;AAEA,SAAS,aACP,eAAmC,EACnC,eAAmC;IAEnC,KAAK,MAAM,YAAY,gBAAiB;QACtC,cAAc,UAAU;IAC1B;IAEA,KAAK,MAAM,YAAY,gBAAiB;QACtC,cAAc,UAAU;IAC1B;IAEA,6DAA6D;IAC7D,0EAA0E;IAC1E,MAAM,wBAAwB,IAAI;IAClC,KAAK,MAAM,YAAY,gBAAiB;QACtC,MAAM,YAAY,WAAW,CAAC,SAAS;QACvC,sBAAsB,GAAG,CAAC,UAAU,WAAW;QAC/C,OAAO,WAAW,CAAC,SAAS;IAC9B;IAEA,uEAAuE;IACvE,YAAY;IAEZ,OAAO;QAAE;IAAsB;AACjC;AAEA;;;;;;;;;;;;CAYC,GACD,SAAS,cAAc,QAAkB,EAAE,IAAyB;IAClE,MAAM,SAAS,WAAW,CAAC,SAAS;IACpC,IAAI,CAAC,QAAQ;QACX;IACF;IAEA,MAAM,WAAW,eAAe,GAAG,CAAC;IACpC,MAAM,OAAO,CAAC;IAEd,mEAAmE;IACnE,qBAAqB;IACrB,KAAK,MAAM,kBAAkB,SAAS,eAAe,CAAE;QACrD,eAAe;IACjB;IAEA,0EAA0E;IAC1E,2CAA2C;IAC3C,OAAO,GAAG,CAAC,MAAM,GAAG;IAEpB,eAAe,MAAM,CAAC;IAEtB,sEAAsE;IAEtE,8DAA8D;IAC9D,wEAAwE;IACxE,kBAAkB;IAClB,KAAK,MAAM,WAAW,OAAO,QAAQ,CAAE;QACrC,MAAM,QAAQ,WAAW,CAAC,QAAQ;QAClC,IAAI,CAAC,OAAO;YACV;QACF;QAEA,MAAM,MAAM,MAAM,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE;QAC3C,IAAI,OAAO,GAAG;YACZ,MAAM,OAAO,CAAC,MAAM,CAAC,KAAK;QAC5B;IACF;IAEA,OAAQ;QACN,KAAK;YACH,OAAO,WAAW,CAAC,OAAO,EAAE,CAAC;YAC7B,cAAc,MAAM,CAAC,OAAO,EAAE;YAC9B;QACF,KAAK;YACH,cAAc,GAAG,CAAC,OAAO,EAAE,EAAE;YAC7B;QACF;YACE,UAAU,MAAM,CAAC,OAAS,CAAC,cAAc,EAAE,KAAK,CAAC;IACrD;AACF;AAEA,SAAS,WACP,2BAGG,EACH,kBAAgD,EAChD,qBAAqD,EACrD,WAA+B;IAE/B,2BAA2B;IAC3B,KAAK,MAAM,CAAC,UAAU,QAAQ,IAAI,mBAAmB,OAAO,GAAI;QAC9D,eAAe,CAAC,SAAS,GAAG;IAC9B;IAEA,gDAAgD;IAEhD,wEAAwE;IAExE,qDAAqD;IACrD,KAAK,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,IAAI,4BAA6B;QACpE,IAAI;YACF,kBAAkB,UAAU;gBAC1B,IAAI;gBACJ,SAAS,sBAAsB,GAAG,CAAC;YACrC;QACF,EAAE,OAAO,KAAK;YACZ,IAAI,OAAO,iBAAiB,YAAY;gBACtC,IAAI;oBACF,aAAa,KAAK;wBAAE;wBAAU,QAAQ,WAAW,CAAC,SAAS;oBAAC;gBAC9D,EAAE,OAAO,MAAM;oBACb,YAAY;oBACZ,YAAY;gBACd;YACF,OAAO;gBACL,YAAY;YACd;QACF;IACF;AACF;AAEA;;CAEC,GACD,SAAS,UAAU,KAAY,EAAE,cAAoC;IACnE,MAAM,IAAI,MAAM,CAAC,WAAW,EAAE,eAAe,OAAO,CAAC;AACvD;AAEA,SAAS,YAAY,MAAqB;IACxC,OAAQ,OAAO,IAAI;QACjB,KAAK;YACH,qBAAqB;YACrB;QACF;YACE,UAAU,QAAQ,CAAC,SAAW,CAAC,qBAAqB,EAAE,OAAO,IAAI,CAAC,CAAC;IACvE;AACF;AAEA,SAAS,qBAAqB,MAAuB;IACnD,IAAI,OAAO,MAAM,IAAI,MAAM;QACzB,KAAK,MAAM,UAAU,OAAO,MAAM,CAAE;YAClC,OAAQ,OAAO,IAAI;gBACjB,KAAK;oBACH,4BAA4B;oBAC5B;gBACF;oBACE,UAAU,QAAQ,CAAC,SAAW,CAAC,qBAAqB,EAAE,OAAO,IAAI,CAAC,CAAC;YACvE;QACF;IACF;IAEA,IAAI,OAAO,MAAM,IAAI,MAAM;QACzB,KAAK,MAAM,CAAC,WAAW,YAAY,IAAI,OAAO,OAAO,CAAC,OAAO,MAAM,EAAG;YACpE,OAAQ,YAAY,IAAI;gBACtB,KAAK;oBACH,QAAQ,SAAS,CAAC,WAAW;wBAAE,IAAI;oBAAoB;oBACvD;gBACF,KAAK;oBACH,QAAQ,WAAW,GAAG;oBACtB;gBACF,KAAK;oBACH,QAAQ,WAAW,GAAG;oBACtB;gBACF,KAAK;oBACH,UACE,YAAY,WAAW,EACvB,CAAC,cACC,CAAC,6BAA6B,EAAE,KAAK,SAAS,CAAC,aAAa,CAAC,CAAC;gBAEpE;oBACE,UACE,aACA,CAAC,cAAgB,CAAC,2BAA2B,EAAE,YAAY,IAAI,CAAC,CAAC;YAEvE;QACF;IACF;AACF;AAEA,SAAS,4BAA4B,MAA8B;IACjE,MAAM,EAAE,UAAU,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,EAAE,GAAG;IACtC,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,aAAa,EAAE,GAAG,sBACtD,SACA;IAEF,MAAM,EAAE,eAAe,EAAE,kBAAkB,EAAE,GAAG,uBAC9C,OACA;IAEF,MAAM,EAAE,eAAe,EAAE,GAAG,kBAAkB,aAAa;IAE3D,cAAc,iBAAiB,iBAAiB;AAClD;AAEA,SAAS,wBAAwB,eAA8B;IAC7D,IAAI,yBAAyB,IAAI,GAAG,GAAG;QACrC,2BAA2B,0BAA0B,OAAO,CAAC,CAAC;YAC5D,gBAAgB,GAAG,CAAC;QACtB;QAEA,yBAAyB,KAAK;IAChC;IAEA,OAAO;AACT;AAEA,SAAS,cACP,eAA8B,EAC9B,eAAmC,EACnC,kBAAgD;IAEhD,kBAAkB,wBAAwB;IAE1C,MAAM,8BACJ,mCAAmC;IAErC,MAAM,EAAE,qBAAqB,EAAE,GAAG,aAChC,iBACA;IAGF,4FAA4F;IAC5F,IAAI;IAEJ,SAAS,YAAY,GAAQ;QAC3B,IAAI,CAAC,OAAO,QAAQ;IACtB;IAEA,WACE,6BACA,oBACA,uBACA;IAGF,IAAI,OAAO;QACT,MAAM;IACR;IAEA,IAAI,yBAAyB,IAAI,GAAG,GAAG;QACrC,cAAc,IAAI,OAAO,EAAE,EAAE,IAAI;IACnC;AACF;AAEA,SAAS,sBACP,OAAgD,EAChD,OAAuD;IAQvD,MAAM,cAAc,IAAI;IACxB,MAAM,gBAAgB,IAAI;IAC1B,MAAM,QAA8C,IAAI;IACxD,MAAM,WAAW,IAAI;IACrB,MAAM,UAAyB,IAAI;IAEnC,KAAK,MAAM,CAAC,WAAW,kBAAkB,IAAI,OAAO,OAAO,CAAC,SAAU;QACpE,OAAQ,kBAAkB,IAAI;YAC5B,KAAK;gBAAS;oBACZ,MAAM,cAAc,IAAI,IAAI,kBAAkB,OAAO;oBACrD,KAAK,MAAM,YAAY,YAAa;wBAClC,MAAM,GAAG,CAAC,UAAU,OAAO,CAAC,SAAS;oBACvC;oBACA,YAAY,GAAG,CAAC,WAAW;oBAC3B;gBACF;YACA,KAAK;gBAAW;oBACd,sDAAsD;oBACtD,MAAM,gBAAgB,IAAI,IAAI,gBAAgB,GAAG,CAAC;oBAClD,KAAK,MAAM,YAAY,cAAe;wBACpC,QAAQ,GAAG,CAAC;oBACd;oBACA,cAAc,GAAG,CAAC,WAAW;oBAC7B;gBACF;YACA,KAAK;gBAAW;oBACd,MAAM,cAAc,IAAI,IAAI,kBAAkB,KAAK;oBACnD,MAAM,gBAAgB,IAAI,IAAI,kBAAkB,OAAO;oBACvD,KAAK,MAAM,YAAY,YAAa;wBAClC,MAAM,GAAG,CAAC,UAAU,OAAO,CAAC,SAAS;oBACvC;oBACA,KAAK,MAAM,YAAY,cAAe;wBACpC,QAAQ,GAAG,CAAC;oBACd;oBACA,YAAY,GAAG,CAAC,WAAW;oBAC3B,cAAc,GAAG,CAAC,WAAW;oBAC7B;gBACF;YACA;gBACE,UACE,mBACA,CAAC,oBACC,CAAC,kCAAkC,EAAE,kBAAkB,IAAI,CAAC,CAAC;QAErE;IACF;IAEA,oFAAoF;IACpF,yFAAyF;IACzF,uCAAuC;IACvC,KAAK,MAAM,YAAY,MAAM,IAAI,GAAI;QACnC,IAAI,QAAQ,GAAG,CAAC,WAAW;YACzB,MAAM,MAAM,CAAC;YACb,QAAQ,MAAM,CAAC;QACjB;IACF;IAEA,KAAK,MAAM,CAAC,UAAU,MAAM,IAAI,OAAO,OAAO,CAAC,SAAU;QACvD,gFAAgF;QAChF,kBAAkB;QAClB,gFAAgF;QAChF,kDAAkD;QAClD,IAAI,CAAC,MAAM,GAAG,CAAC,WAAW;YACxB,SAAS,GAAG,CAAC,UAAU;QACzB;IACF;IAEA,OAAO;QAAE;QAAO;QAAS;QAAU;QAAa;IAAc;AAChE;AAkBA,SAAS,yBAAyB,QAAkB;IAClD,MAAM,kBAAiC,IAAI;IAI3C,MAAM,QAAqB;QACzB;YACE;YACA,iBAAiB,EAAE;QACrB;KACD;IAED,IAAI;IACJ,MAAQ,WAAW,MAAM,KAAK,GAAK;QACjC,MAAM,EAAE,QAAQ,EAAE,eAAe,EAAE,GAAG;QAEtC,IAAI,YAAY,MAAM;YACpB,gBAAgB,GAAG,CAAC;QACtB;QAEA,sEAAsE;QACtE,qCAAqC;QACrC,IAAI,aAAa,WAAW;YAC1B,OAAO;gBACL,MAAM;gBACN;YACF;QACF;QAEA,MAAM,SAAS,WAAW,CAAC,SAAS;QACpC,MAAM,WAAW,eAAe,GAAG,CAAC;QAEpC,IACE,qEAAqE;QACrE,0DAA0D;QAC1D,CAAC,UAEA,SAAS,YAAY,IAAI,CAAC,SAAS,eAAe,EACnD;YACA;QACF;QAEA,IAAI,SAAS,YAAY,EAAE;YACzB,OAAO;gBACL,MAAM;gBACN;gBACA;YACF;QACF;QAEA,IAAI,eAAe,GAAG,CAAC,WAAW;YAChC,MAAM,IAAI,CAAC;gBACT,UAAU;gBACV,iBAAiB;uBAAI;oBAAiB;iBAAS;YACjD;YACA;QACF;QAEA,KAAK,MAAM,YAAY,OAAO,OAAO,CAAE;YACrC,MAAM,SAAS,WAAW,CAAC,SAAS;YAEpC,IAAI,CAAC,QAAQ;gBAEX;YACF;YAEA,4DAA4D;YAC5D,qBAAqB;YAErB,MAAM,IAAI,CAAC;gBACT,UAAU;gBACV,iBAAiB;uBAAI;oBAAiB;iBAAS;YACjD;QACF;IACF;IAEA,OAAO;QACL,MAAM;QACN;QACA;IACF;AACF;AAEA,SAAS,YAAY,aAAwB,EAAE,MAAqB;IAClE,OAAQ,OAAO,IAAI;QACjB,KAAK;YAAW;gBACd,4FAA4F;gBAC5F,YAAY,OAAO,WAAW;gBAC9B;YACF;QACA,KAAK;YAAW;gBACd,iEAAiE;gBACjE,qEAAqE;gBACrE,aAAa;gBACb,QAAQ,OAAO;gBACf;YACF;QACA,KAAK;YAAY;gBACf,+GAA+G;gBAC/G,kCAAkC;gBAClC,mGAAmG;gBACnG,6DAA6D;gBAC7D,IAAI,kBAAkB,GAAG,CAAC,gBAAgB;oBACxC,QAAQ,OAAO;gBACjB,OAAO;oBACL,iBAAiB;gBACnB;gBACA;YACF;QACA;YACE,MAAM,IAAI,MAAM,CAAC,qBAAqB,EAAE,OAAO,IAAI,CAAC,CAAC;IACzD;AACF;AAEA,SAAS,gBACP,QAAkB,EAClB,OAAgB;IAEhB,MAAM,WAAqB;QACzB,cAAc;QACd,cAAc;QACd,iBAAiB;QACjB,iBAAiB,EAAE;IACrB;IAEA,MAAM,MAAW;QACf,qEAAqE;QACrE,wEAAwE;QACxE,uCAAuC;QACvC,QAAQ;QAER,MAAM,WAAW,CAAC;QAElB,mEAAmE;QACnE,QAAQ,CACN,SACA,WACA;YAEA,IAAI,YAAY,WAAW;gBACzB,SAAS,YAAY,GAAG;YAC1B,OAAO,IAAI,OAAO,YAAY,YAAY;gBACxC,SAAS,YAAY,GAAG;YAC1B,OAAO;gBACL,MAAM,IAAI,MAAM;YAClB;QACF;QAEA,SAAS,CAAC;YACR,IAAI,QAAQ,WAAW;gBACrB,SAAS,YAAY,GAAG;YAC1B,OAAO;gBACL,MAAM,IAAI,MAAM;YAClB;QACF;QAEA,SAAS,CAAC;YACR,SAAS,eAAe,CAAC,IAAI,CAAC;QAChC;QAEA,mBAAmB,CAAC;YAClB,SAAS,eAAe,CAAC,IAAI,CAAC;QAChC;QAEA,sBAAsB,CAAC;YACrB,MAAM,MAAM,SAAS,eAAe,CAAC,OAAO,CAAC;YAC7C,IAAI,OAAO,GAAG;gBACZ,SAAS,eAAe,CAAC,MAAM,CAAC,KAAK;YACvC;QACF;QAEA,YAAY;YACV,SAAS,eAAe,GAAG;YAC3B,yBAAyB,GAAG,CAAC;QAC/B;QAEA,qEAAqE;QACrE,uEAAuE;QACvE,iCAAiC;QACjC,QAAQ,IAAM;QAEd,2EAA2E;QAC3E,kBAAkB,CAAC,YAAc;QACjC,qBAAqB,CAAC,YAAc;QAEpC,2EAA2E;QAC3E,yEAAyE;QACzE,iBAAiB;QACjB,OAAO,IAAM,QAAQ,OAAO,CAAC;IAC/B;IAEA,OAAO;QAAE;QAAK;IAAS;AACzB;AAEA;;CAEC,GACD,SAAS,iBAAiB,QAAkB,EAAE,SAAoB;IAChE,IAAI,eAAe,gBAAgB,GAAG,CAAC;IACvC,IAAI,CAAC,cAAc;QACjB,eAAe,IAAI,IAAI;YAAC;SAAU;QAClC,gBAAgB,GAAG,CAAC,UAAU;IAChC,OAAO;QACL,aAAa,GAAG,CAAC;IACnB;IAEA,IAAI,eAAe,gBAAgB,GAAG,CAAC;IACvC,IAAI,CAAC,cAAc;QACjB,eAAe,IAAI,IAAI;YAAC;SAAS;QACjC,gBAAgB,GAAG,CAAC,WAAW;IACjC,OAAO;QACL,aAAa,GAAG,CAAC;IACnB;AACF;AAEA;;;;CAIC,GACD,SAAS,oBAAoB,QAAkB;IAC7C,MAAM,mBAAmB,gBAAgB,GAAG,CAAC;IAC7C,IAAI,oBAAoB,MAAM;QAC5B,OAAO;IACT;IAEA,OAAO,iBAAiB,MAAM,GAAG,IAAI,GAAG,KAAK;AAC/C;AAEA;;;CAGC,GACD,SAAS,sBACP,QAAkB,EAClB,SAAoB;IAEpB,MAAM,eAAe,gBAAgB,GAAG,CAAC;IACzC,aAAa,MAAM,CAAC;IAEpB,MAAM,eAAe,gBAAgB,GAAG,CAAC;IACzC,aAAa,MAAM,CAAC;IAEpB,MAAM,qBAAqB,aAAa,IAAI,KAAK;IACjD,IAAI,oBAAoB;QACtB,gBAAgB,MAAM,CAAC;IACzB;IAEA,MAAM,oBAAoB,aAAa,IAAI,KAAK;IAChD,IAAI,mBAAmB;QACrB,gBAAgB,MAAM,CAAC;IACzB;IAEA,OAAO;AACT;AAEA;;CAEC,GACD,SAAS,iBAAiB,aAAwB;IAChD,MAAM,aAAa,mBAAmB,GAAG,CAAC;IAC1C,IAAI,cAAc,MAAM;QACtB,OAAO;IACT;IACA,mBAAmB,MAAM,CAAC;IAE1B,KAAK,MAAM,aAAa,WAAY;QAClC,MAAM,kBAAkB,mBAAmB,GAAG,CAAC;QAC/C,gBAAgB,MAAM,CAAC;QAEvB,IAAI,gBAAgB,IAAI,KAAK,GAAG;YAC9B,mBAAmB,MAAM,CAAC;YAC1B,aAAa;QACf;IACF;IAEA,yEAAyE;IACzE,sCAAsC;IACtC,QAAQ,WAAW,GAAG;IAEtB,OAAO;AACT;AAEA;;;;CAIC,GACD,SAAS,aAAa,SAAoB;IACxC,qEAAqE;IACrE,wFAAwF;IACxF,QAAQ,WAAW,GAAG;IAEtB,MAAM,eAAe,gBAAgB,GAAG,CAAC;IACzC,IAAI,gBAAgB,MAAM;QACxB,OAAO;IACT;IACA,aAAa,MAAM,CAAC;IAEpB,KAAK,MAAM,YAAY,aAAc;QACnC,MAAM,eAAe,gBAAgB,GAAG,CAAC;QACzC,aAAa,MAAM,CAAC;QAEpB,MAAM,oBAAoB,aAAa,IAAI,KAAK;QAChD,IAAI,mBAAmB;YACrB,gBAAgB,MAAM,CAAC;YACvB,cAAc,UAAU;YACxB,iBAAiB,MAAM,CAAC;QAC1B;IACF;IAEA,OAAO;AACT;AAEA;;CAEC,GACD,SAAS,yBACP,QAAkB,EAClB,SAAoB;IAEpB,OAAO,kBAAkB,UAAU;QAAE,IAAI;QAAsB;IAAU;AAC3E;AAEA;;CAEC,GACD,SAAS,8BACP,QAAkB,EAClB,SAAoB;IAEpB,MAAM,SAAS,WAAW,CAAC,SAAS;IACpC,IAAI,QAAQ;QACV,IAAI,OAAO,KAAK,EAAE;YAChB,MAAM,OAAO,KAAK;QACpB;QACA,OAAO;IACT;IAEA,OAAO,kBAAkB,UAAU;QAAE,IAAI;QAAsB;IAAU;AAC3E;AAEA;;CAEC,GACD,SAAS,oBAAoB,SAAoB;IAC/C,OAAO,CAAC,EAAE,gBAAgB,EAAE,UACzB,KAAK,CAAC,KACN,GAAG,CAAC,CAAC,IAAM,mBAAmB,IAC9B,IAAI,CAAC,KAAK,CAAC;AAChB;AAEA;;CAEC,GACD,SAAS,kBACP,mBAAwC,EACxC,SAAoB;IAEpB,oBAAoB,IAAI,CAAC;QACvB,UAAU,IAAI;QACd,YAAY,IAAI,CAAC,MAAM,UAAU,IAAI;KACtC;IAED,+CAA+C;IAC/C,MAAM,SAAS,IAAI,IAAI,UAAU,MAAM,CAAC,GAAG,CAAC;IAC5C,mBAAmB,GAAG,CAAC,UAAU,IAAI,EAAE;IACvC,KAAK,MAAM,aAAa,OAAQ;QAC9B,IAAI,kBAAkB,mBAAmB,GAAG,CAAC;QAC7C,IAAI,CAAC,iBAAiB;YACpB,kBAAkB,IAAI,IAAI;gBAAC,UAAU,IAAI;aAAC;YAC1C,mBAAmB,GAAG,CAAC,WAAW;QACpC,OAAO;YACL,gBAAgB,GAAG,CAAC,UAAU,IAAI;QACpC;IACF;IAEA,IAAI,UAAU,MAAM,KAAK,SAAS;QAChC,uBAAuB,UAAU,IAAI;IACvC;AACF;AAEA;;;;CAIC,GACD,SAAS,uBAAuB,aAAwB;IACtD,kBAAkB,GAAG,CAAC;AACxB;AAEA,SAAS,cAAc,CACrB,WACA,cACA,cACkB;IAClB,KAAK,MAAM,CAAC,UAAU,cAAc,IAAI,OAAO,OAAO,CAAC,cAAe;QACpE,IAAI,CAAC,eAAe,CAAC,SAAS,EAAE;YAC9B,eAAe,CAAC,SAAS,GAAG;QAC9B;QACA,iBAAiB,UAAU;IAC7B;IAEA,OAAO,QAAQ,aAAa,CAAC,WAAW;AAC1C;AAEA,WAAW,gCAAgC,KAAK,EAAE;AAElD,MAAM,uBAAuB,WAAW,qBAAqB;AAC7D,IAAI,MAAM,OAAO,CAAC,uBAAuB;IACvC,KAAK,MAAM,aAAa,qBAAsB;QAC5C,kBAAkB,WAAW,gCAAgC,EAAE;IACjE;AACF;AAEA,WAAW,qBAAqB,GAAG;IACjC,MAAM,CAAC;QACL,kBAAkB,WAAW,gCAAgC,EAAG;IAClE;AACF"}}, - {"offset": {"line": 1331, "column": 0}, "map": {"version":3,"sources":["/turbopack/[turbopack]/dev/runtime/dom/runtime-backend-dom.ts"],"sourcesContent":["/**\n * This file contains the runtime code specific to the Turbopack development\n * ECMAScript DOM runtime.\n *\n * It will be appended to the base development runtime code.\n */\n\n/// \n/// \n\ntype ChunkResolver = {\n resolved: boolean;\n resolve: () => void;\n reject: (error?: Error) => void;\n promise: Promise;\n};\n\nlet BACKEND: RuntimeBackend;\n\nfunction augmentContext(context: TurbopackDevBaseContext): TurbopackDevContext {\n return context;\n}\n\nfunction fetchWebAssembly(wasmChunkPath: ChunkPath) {\n return fetch(getChunkRelativeUrl(wasmChunkPath));\n}\n\nasync function loadWebAssembly(\n _source: SourceInfo,\n wasmChunkPath: ChunkPath,\n importsObj: WebAssembly.Imports\n): Promise {\n const req = fetchWebAssembly(wasmChunkPath);\n\n const { instance } = await WebAssembly.instantiateStreaming(req, importsObj);\n\n return instance.exports;\n}\n\nasync function loadWebAssemblyModule(\n _source: SourceInfo,\n wasmChunkPath: ChunkPath\n): Promise {\n const req = fetchWebAssembly(wasmChunkPath);\n\n return await WebAssembly.compileStreaming(req);\n}\n\n(() => {\n BACKEND = {\n async registerChunk(chunkPath, params) {\n const resolver = getOrCreateResolver(chunkPath);\n resolver.resolve();\n\n if (params == null) {\n return;\n }\n\n for (const otherChunkData of params.otherChunks) {\n const otherChunkPath = getChunkPath(otherChunkData);\n // Chunk might have started loading, so we want to avoid triggering another load.\n getOrCreateResolver(otherChunkPath);\n }\n\n // This waits for chunks to be loaded, but also marks included items as available.\n await Promise.all(\n params.otherChunks.map((otherChunkData) =>\n loadChunk({ type: SourceType.Runtime, chunkPath }, otherChunkData)\n )\n );\n\n if (params.runtimeModuleIds.length > 0) {\n for (const moduleId of params.runtimeModuleIds) {\n getOrInstantiateRuntimeModule(moduleId, chunkPath);\n }\n }\n },\n\n loadChunk(chunkPath, source) {\n return doLoadChunk(chunkPath, source);\n },\n\n unloadChunk(chunkPath) {\n deleteResolver(chunkPath);\n\n const chunkUrl = getChunkRelativeUrl(chunkPath);\n // TODO(PACK-2140): remove this once all filenames are guaranteed to be escaped.\n const decodedChunkUrl = decodeURI(chunkUrl);\n\n if (chunkPath.endsWith(\".css\")) {\n const links = document.querySelectorAll(\n `link[href=\"${chunkUrl}\"],link[href^=\"${chunkUrl}?\"],link[href=\"${decodedChunkUrl}\"],link[href^=\"${decodedChunkUrl}?\"]`\n );\n for (const link of Array.from(links)) {\n link.remove();\n }\n } else if (chunkPath.endsWith(\".js\")) {\n // Unloading a JS chunk would have no effect, as it lives in the JS\n // runtime once evaluated.\n // However, we still want to remove the script tag from the DOM to keep\n // the HTML somewhat consistent from the user's perspective.\n const scripts = document.querySelectorAll(\n `script[src=\"${chunkUrl}\"],script[src^=\"${chunkUrl}?\"],script[src=\"${decodedChunkUrl}\"],script[src^=\"${decodedChunkUrl}?\"]`\n );\n for (const script of Array.from(scripts)) {\n script.remove();\n }\n } else {\n throw new Error(`can't infer type of chunk from path ${chunkPath}`);\n }\n },\n\n reloadChunk(chunkPath) {\n return new Promise((resolve, reject) => {\n if (!chunkPath.endsWith(\".css\")) {\n reject(new Error(\"The DOM backend can only reload CSS chunks\"));\n return;\n }\n\n const chunkUrl = getChunkRelativeUrl(chunkPath);\n const decodedChunkUrl = decodeURI(chunkUrl);\n\n const previousLinks = document.querySelectorAll(\n `link[rel=stylesheet][href=\"${chunkUrl}\"],link[rel=stylesheet][href^=\"${chunkUrl}?\"],link[rel=stylesheet][href=\"${decodedChunkUrl}\"],link[rel=stylesheet][href^=\"${decodedChunkUrl}?\"]`\n );\n\n if (previousLinks.length == 0) {\n reject(new Error(`No link element found for chunk ${chunkPath}`));\n return;\n }\n\n const link = document.createElement(\"link\");\n link.rel = \"stylesheet\";\n\n if (navigator.userAgent.includes(\"Firefox\")) {\n // Firefox won't reload CSS files that were previously loaded on the current page,\n // we need to add a query param to make sure CSS is actually reloaded from the server.\n //\n // I believe this is this issue: https://bugzilla.mozilla.org/show_bug.cgi?id=1037506\n //\n // Safari has a similar issue, but only if you have a `` tag\n // pointing to the same URL as the stylesheet: https://bugs.webkit.org/show_bug.cgi?id=187726\n link.href = `${chunkUrl}?ts=${Date.now()}`;\n } else {\n link.href = chunkUrl;\n }\n\n link.onerror = () => {\n reject();\n };\n link.onload = () => {\n // First load the new CSS, then remove the old ones. This prevents visible\n // flickering that would happen in-between removing the previous CSS and\n // loading the new one.\n for (const previousLink of Array.from(previousLinks))\n previousLink.remove();\n\n // CSS chunks do not register themselves, and as such must be marked as\n // loaded instantly.\n resolve();\n };\n\n // Make sure to insert the new CSS right after the previous one, so that\n // its precedence is higher.\n previousLinks[0].parentElement!.insertBefore(\n link,\n previousLinks[0].nextSibling\n );\n });\n },\n\n restart: () => self.location.reload(),\n };\n\n /**\n * Maps chunk paths to the corresponding resolver.\n */\n const chunkResolvers: Map = new Map();\n\n function getOrCreateResolver(chunkPath: ChunkPath): ChunkResolver {\n let resolver = chunkResolvers.get(chunkPath);\n if (!resolver) {\n let resolve: () => void;\n let reject: (error?: Error) => void;\n const promise = new Promise((innerResolve, innerReject) => {\n resolve = innerResolve;\n reject = innerReject;\n });\n resolver = {\n resolved: false,\n promise,\n resolve: () => {\n resolver!.resolved = true;\n resolve();\n },\n reject: reject!,\n };\n chunkResolvers.set(chunkPath, resolver);\n }\n return resolver;\n }\n\n function deleteResolver(chunkPath: ChunkPath) {\n chunkResolvers.delete(chunkPath);\n }\n\n /**\n * Loads the given chunk, and returns a promise that resolves once the chunk\n * has been loaded.\n */\n async function doLoadChunk(chunkPath: ChunkPath, source: SourceInfo) {\n const resolver = getOrCreateResolver(chunkPath);\n if (resolver.resolved) {\n return resolver.promise;\n }\n\n if (source.type === SourceType.Runtime) {\n // We don't need to load chunks references from runtime code, as they're already\n // present in the DOM.\n\n if (chunkPath.endsWith(\".css\")) {\n // CSS chunks do not register themselves, and as such must be marked as\n // loaded instantly.\n resolver.resolve();\n }\n\n // We need to wait for JS chunks to register themselves within `registerChunk`\n // before we can start instantiating runtime modules, hence the absence of\n // `resolver.resolve()` in this branch.\n\n return resolver.promise;\n }\n\n const chunkUrl = getChunkRelativeUrl(chunkPath);\n const decodedChunkUrl = decodeURI(chunkUrl);\n\n if (chunkPath.endsWith(\".css\")) {\n const previousLinks = document.querySelectorAll(\n `link[rel=stylesheet][href=\"${chunkUrl}\"],link[rel=stylesheet][href^=\"${chunkUrl}?\"],link[rel=stylesheet][href=\"${decodedChunkUrl}\"],link[rel=stylesheet][href^=\"${decodedChunkUrl}?\"]`\n );\n if (previousLinks.length > 0) {\n // CSS chunks do not register themselves, and as such must be marked as\n // loaded instantly.\n resolver.resolve();\n } else {\n const link = document.createElement(\"link\");\n link.rel = \"stylesheet\";\n link.href = chunkUrl;\n link.onerror = () => {\n resolver.reject();\n };\n link.onload = () => {\n // CSS chunks do not register themselves, and as such must be marked as\n // loaded instantly.\n resolver.resolve();\n };\n document.body.appendChild(link);\n }\n } else if (chunkPath.endsWith(\".js\")) {\n const previousScripts = document.querySelectorAll(\n `script[src=\"${chunkUrl}\"],script[src^=\"${chunkUrl}?\"],script[src=\"${decodedChunkUrl}\"],script[src^=\"${decodedChunkUrl}?\"]`\n );\n if (previousScripts.length > 0) {\n // There is this edge where the script already failed loading, but we\n // can't detect that. The Promise will never resolve in this case.\n for (const script of Array.from(previousScripts)) {\n script.addEventListener(\"error\", () => {\n resolver.reject();\n });\n }\n } else {\n const script = document.createElement(\"script\");\n script.src = chunkUrl;\n // We'll only mark the chunk as loaded once the script has been executed,\n // which happens in `registerChunk`. Hence the absence of `resolve()` in\n // this branch.\n script.onerror = () => {\n resolver.reject();\n };\n document.body.appendChild(script);\n }\n } else {\n throw new Error(`can't infer type of chunk from path ${chunkPath}`);\n }\n\n return resolver.promise;\n }\n})();\n\nfunction _eval({ code, url, map }: EcmascriptModuleEntry): ModuleFactory {\n code += `\\n\\n//# sourceURL=${encodeURI(\n location.origin + CHUNK_BASE_PATH + url\n )}`;\n if (map)\n code += `\\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,${btoa(\n map\n )}`;\n return eval(code);\n}\n"],"names":[],"mappings":"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"}}, + {"offset": {"line": 13, "column": 0}, "map": {"version":3,"sources":["turbopack://[turbopack]/shared/runtime-utils.ts"],"sourcesContent":["/**\n * This file contains runtime types and functions that are shared between all\n * TurboPack ECMAScript runtimes.\n *\n * It will be prepended to the runtime code of each runtime.\n */\n\n/* eslint-disable @next/next/no-assign-module-variable */\n\n/// \n\ninterface Exports {\n __esModule?: boolean;\n\n [key: string]: any;\n}\n\ntype EsmNamespaceObject = Record;\n\nconst REEXPORTED_OBJECTS = Symbol(\"reexported objects\");\n\ninterface BaseModule {\n exports: Function | Exports | Promise | AsyncModulePromise;\n error: Error | undefined;\n loaded: boolean;\n id: ModuleId;\n children: ModuleId[];\n parents: ModuleId[];\n namespaceObject?:\n | EsmNamespaceObject\n | Promise\n | AsyncModulePromise;\n [REEXPORTED_OBJECTS]?: any[];\n}\n\ninterface Module extends BaseModule {}\n\ntype ModuleContextMap = Record;\n\ninterface ModuleContextEntry {\n id: () => ModuleId;\n module: () => any;\n}\n\ninterface ModuleContext {\n // require call\n (moduleId: ModuleId): Exports | EsmNamespaceObject;\n\n // async import call\n import(moduleId: ModuleId): Promise;\n\n keys(): ModuleId[];\n\n resolve(moduleId: ModuleId): ModuleId;\n}\n\ntype GetOrInstantiateModuleFromParent = (\n moduleId: ModuleId,\n parentModule: Module\n) => Module;\n\nconst hasOwnProperty = Object.prototype.hasOwnProperty;\nconst toStringTag = typeof Symbol !== \"undefined\" && Symbol.toStringTag;\n\nfunction defineProp(\n obj: any,\n name: PropertyKey,\n options: PropertyDescriptor & ThisType\n) {\n if (!hasOwnProperty.call(obj, name))\n Object.defineProperty(obj, name, options);\n}\n\n/**\n * Adds the getters to the exports object.\n */\nfunction esm(exports: Exports, getters: Record any>) {\n defineProp(exports, \"__esModule\", { value: true });\n if (toStringTag) defineProp(exports, toStringTag, { value: \"Module\" });\n for (const key in getters) {\n defineProp(exports, key, { get: getters[key], enumerable: true });\n }\n}\n\n/**\n * Makes the module an ESM with exports\n */\nfunction esmExport(\n module: Module,\n exports: Exports,\n getters: Record any>\n) {\n module.namespaceObject = module.exports;\n esm(exports, getters);\n}\n\nfunction ensureDynamicExports(module: Module, exports: Exports) {\n let reexportedObjects = module[REEXPORTED_OBJECTS];\n\n if (!reexportedObjects) {\n reexportedObjects = module[REEXPORTED_OBJECTS] = [];\n module.exports = module.namespaceObject = new Proxy(exports, {\n get(target, prop) {\n if (\n hasOwnProperty.call(target, prop) ||\n prop === \"default\" ||\n prop === \"__esModule\"\n ) {\n return Reflect.get(target, prop);\n }\n for (const obj of reexportedObjects!) {\n const value = Reflect.get(obj, prop);\n if (value !== undefined) return value;\n }\n return undefined;\n },\n ownKeys(target) {\n const keys = Reflect.ownKeys(target);\n for (const obj of reexportedObjects!) {\n for (const key of Reflect.ownKeys(obj)) {\n if (key !== \"default\" && !keys.includes(key)) keys.push(key);\n }\n }\n return keys;\n },\n });\n }\n}\n\n/**\n * Dynamically exports properties from an object\n */\nfunction dynamicExport(\n module: Module,\n exports: Exports,\n object: Record\n) {\n ensureDynamicExports(module, exports);\n\n if (typeof object === \"object\" && object !== null) {\n module[REEXPORTED_OBJECTS]!.push(object);\n }\n}\n\nfunction exportValue(module: Module, value: any) {\n module.exports = value;\n}\n\nfunction exportNamespace(module: Module, namespace: any) {\n module.exports = module.namespaceObject = namespace;\n}\n\nfunction createGetter(obj: Record, key: string | symbol) {\n return () => obj[key];\n}\n\n/**\n * @returns prototype of the object\n */\nconst getProto: (obj: any) => any = Object.getPrototypeOf\n ? (obj) => Object.getPrototypeOf(obj)\n : (obj) => obj.__proto__;\n\n/** Prototypes that are not expanded for exports */\nconst LEAF_PROTOTYPES = [null, getProto({}), getProto([]), getProto(getProto)];\n\n/**\n * @param raw\n * @param ns\n * @param allowExportDefault\n * * `false`: will have the raw module as default export\n * * `true`: will have the default property as default export\n */\nfunction interopEsm(\n raw: Exports,\n ns: EsmNamespaceObject,\n allowExportDefault?: boolean\n) {\n const getters: { [s: string]: () => any } = Object.create(null);\n for (\n let current = raw;\n (typeof current === \"object\" || typeof current === \"function\") &&\n !LEAF_PROTOTYPES.includes(current);\n current = getProto(current)\n ) {\n for (const key of Object.getOwnPropertyNames(current)) {\n getters[key] = createGetter(raw, key);\n }\n }\n\n // this is not really correct\n // we should set the `default` getter if the imported module is a `.cjs file`\n if (!(allowExportDefault && \"default\" in getters)) {\n getters[\"default\"] = () => raw;\n }\n\n esm(ns, getters);\n return ns;\n}\n\nfunction createNS(raw: BaseModule[\"exports\"]): EsmNamespaceObject {\n if (typeof raw === \"function\") {\n return function (this: any, ...args: any[]) {\n return raw.apply(this, args);\n };\n } else {\n return Object.create(null);\n }\n}\n\nfunction esmImport(\n sourceModule: Module,\n id: ModuleId\n): Exclude {\n const module = getOrInstantiateModuleFromParent(id, sourceModule);\n if (module.error) throw module.error;\n\n // any ES module has to have `module.namespaceObject` defined.\n if (module.namespaceObject) return module.namespaceObject;\n\n // only ESM can be an async module, so we don't need to worry about exports being a promise here.\n const raw = module.exports;\n return (module.namespaceObject = interopEsm(\n raw,\n createNS(raw),\n raw && (raw as any).__esModule\n ));\n}\n\n// Add a simple runtime require so that environments without one can still pass\n// `typeof require` CommonJS checks so that exports are correctly registered.\nconst runtimeRequire =\n typeof require === \"function\"\n ? require\n : function require() {\n throw new Error(\"Unexpected use of runtime require\");\n };\n\nfunction commonJsRequire(sourceModule: Module, id: ModuleId): Exports {\n const module = getOrInstantiateModuleFromParent(id, sourceModule);\n if (module.error) throw module.error;\n return module.exports;\n}\n\n/**\n * `require.context` and require/import expression runtime.\n */\nfunction moduleContext(map: ModuleContextMap): ModuleContext {\n function moduleContext(id: ModuleId): Exports {\n if (hasOwnProperty.call(map, id)) {\n return map[id].module();\n }\n\n const e = new Error(`Cannot find module '${name}'`);\n (e as any).code = \"MODULE_NOT_FOUND\";\n throw e;\n }\n\n moduleContext.keys = (): ModuleId[] => {\n return Object.keys(map);\n };\n\n moduleContext.resolve = (id: ModuleId): ModuleId => {\n if (hasOwnProperty.call(map, id)) {\n return map[id].id();\n }\n\n const e = new Error(`Cannot find module '${name}'`);\n (e as any).code = \"MODULE_NOT_FOUND\";\n throw e;\n };\n\n moduleContext.import = async (id: ModuleId) => {\n return await (moduleContext(id) as Promise);\n };\n\n return moduleContext;\n}\n\n/**\n * Returns the path of a chunk defined by its data.\n */\nfunction getChunkPath(chunkData: ChunkData): ChunkPath {\n return typeof chunkData === \"string\" ? chunkData : chunkData.path;\n}\n\nfunction isPromise(maybePromise: any): maybePromise is Promise {\n return (\n maybePromise != null &&\n typeof maybePromise === \"object\" &&\n \"then\" in maybePromise &&\n typeof maybePromise.then === \"function\"\n );\n}\n\nfunction isAsyncModuleExt(obj: T): obj is AsyncModuleExt & T {\n return turbopackQueues in obj;\n}\n\nfunction createPromise() {\n let resolve: (value: T | PromiseLike) => void;\n let reject: (reason?: any) => void;\n\n const promise = new Promise((res, rej) => {\n reject = rej;\n resolve = res;\n });\n\n return {\n promise,\n resolve: resolve!,\n reject: reject!,\n };\n}\n\n// everything below is adapted from webpack\n// https://github.com/webpack/webpack/blob/6be4065ade1e252c1d8dcba4af0f43e32af1bdc1/lib/runtime/AsyncModuleRuntimeModule.js#L13\n\nconst turbopackQueues = Symbol(\"turbopack queues\");\nconst turbopackExports = Symbol(\"turbopack exports\");\nconst turbopackError = Symbol(\"turbopack error\");\n\ntype AsyncQueueFn = (() => void) & { queueCount: number };\ntype AsyncQueue = AsyncQueueFn[] & { resolved: boolean };\n\nfunction resolveQueue(queue?: AsyncQueue) {\n if (queue && !queue.resolved) {\n queue.resolved = true;\n queue.forEach((fn) => fn.queueCount--);\n queue.forEach((fn) => (fn.queueCount-- ? fn.queueCount++ : fn()));\n }\n}\n\ntype Dep = Exports | AsyncModulePromise | Promise;\n\ntype AsyncModuleExt = {\n [turbopackQueues]: (fn: (queue: AsyncQueue) => void) => void;\n [turbopackExports]: Exports;\n [turbopackError]?: any;\n};\n\ntype AsyncModulePromise = Promise & AsyncModuleExt;\n\nfunction wrapDeps(deps: Dep[]): AsyncModuleExt[] {\n return deps.map((dep) => {\n if (dep !== null && typeof dep === \"object\") {\n if (isAsyncModuleExt(dep)) return dep;\n if (isPromise(dep)) {\n const queue: AsyncQueue = Object.assign([], { resolved: false });\n\n const obj: AsyncModuleExt = {\n [turbopackExports]: {},\n [turbopackQueues]: (fn: (queue: AsyncQueue) => void) => fn(queue),\n };\n\n dep.then(\n (res) => {\n obj[turbopackExports] = res;\n resolveQueue(queue);\n },\n (err) => {\n obj[turbopackError] = err;\n resolveQueue(queue);\n }\n );\n\n return obj;\n }\n }\n\n const ret: AsyncModuleExt = {\n [turbopackExports]: dep,\n [turbopackQueues]: () => {},\n };\n\n return ret;\n });\n}\n\nfunction asyncModule(\n module: Module,\n body: (\n handleAsyncDependencies: (\n deps: Dep[]\n ) => Exports[] | Promise<() => Exports[]>,\n asyncResult: (err?: any) => void\n ) => void,\n hasAwait: boolean\n) {\n const queue: AsyncQueue | undefined = hasAwait\n ? Object.assign([], { resolved: true })\n : undefined;\n\n const depQueues: Set = new Set();\n\n ensureDynamicExports(module, module.exports);\n const exports = module.exports;\n\n const { resolve, reject, promise: rawPromise } = createPromise();\n\n const promise: AsyncModulePromise = Object.assign(rawPromise, {\n [turbopackExports]: exports,\n [turbopackQueues]: (fn) => {\n queue && fn(queue);\n depQueues.forEach(fn);\n promise[\"catch\"](() => {});\n },\n } satisfies AsyncModuleExt);\n\n module.exports = module.namespaceObject = promise;\n\n function handleAsyncDependencies(deps: Dep[]) {\n const currentDeps = wrapDeps(deps);\n\n const getResult = () =>\n currentDeps.map((d) => {\n if (d[turbopackError]) throw d[turbopackError];\n return d[turbopackExports];\n });\n\n const { promise, resolve } = createPromise<() => Exports[]>();\n\n const fn: AsyncQueueFn = Object.assign(() => resolve(getResult), {\n queueCount: 0,\n });\n\n function fnQueue(q: AsyncQueue) {\n if (q !== queue && !depQueues.has(q)) {\n depQueues.add(q);\n if (q && !q.resolved) {\n fn.queueCount++;\n q.push(fn);\n }\n }\n }\n\n currentDeps.map((dep) => dep[turbopackQueues](fnQueue));\n\n return fn.queueCount ? promise : getResult();\n }\n\n function asyncResult(err?: any) {\n if (err) {\n reject((promise[turbopackError] = err));\n } else {\n resolve(exports);\n }\n\n resolveQueue(queue);\n }\n\n body(handleAsyncDependencies, asyncResult);\n\n if (queue) {\n queue.resolved = false;\n }\n}\n\n/**\n * A pseudo \"fake\" URL object to resolve to its relative path.\n *\n * When UrlRewriteBehavior is set to relative, calls to the `new URL()` will construct url without base using this\n * runtime function to generate context-agnostic urls between different rendering context, i.e ssr / client to avoid\n * hydration mismatch.\n *\n * This is based on webpack's existing implementation:\n * https://github.com/webpack/webpack/blob/87660921808566ef3b8796f8df61bd79fc026108/lib/runtime/RelativeUrlRuntimeModule.js\n */\nconst relativeURL = function relativeURL(this: any, inputUrl: string) {\n const realUrl = new URL(inputUrl, \"x:/\");\n const values: Record = {};\n for (const key in realUrl) values[key] = (realUrl as any)[key];\n values.href = inputUrl;\n values.pathname = inputUrl.replace(/[?#].*/, \"\");\n values.origin = values.protocol = \"\";\n values.toString = values.toJSON = (..._args: Array) => inputUrl;\n for (const key in values)\n Object.defineProperty(this, key, {\n enumerable: true,\n configurable: true,\n value: values[key],\n });\n};\n\nrelativeURL.prototype = URL.prototype;\n"],"names":[],"mappings":"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"}}, + {"offset": {"line": 317, "column": 0}, "map": {"version":3,"sources":["turbopack://[turbopack]/dev/runtime/base/runtime-base.ts"],"sourcesContent":["/**\n * This file contains runtime types and functions that are shared between all\n * Turbopack *development* ECMAScript runtimes.\n *\n * It will be appended to the runtime code of each runtime right after the\n * shared runtime utils.\n */\n\n/* eslint-disable @next/next/no-assign-module-variable */\n\n/// \n/// \n/// \n/// \n\n// This file must not use `import` and `export` statements. Otherwise, it\n// becomes impossible to augment interfaces declared in ``d files\n// (e.g. `Module`). Hence, the need for `import()` here.\ntype RefreshRuntimeGlobals =\n import(\"@next/react-refresh-utils/dist/runtime\").RefreshRuntimeGlobals;\n\ndeclare var CHUNK_BASE_PATH: string;\ndeclare var $RefreshHelpers$: RefreshRuntimeGlobals[\"$RefreshHelpers$\"];\ndeclare var $RefreshReg$: RefreshRuntimeGlobals[\"$RefreshReg$\"];\ndeclare var $RefreshSig$: RefreshRuntimeGlobals[\"$RefreshSig$\"];\ndeclare var $RefreshInterceptModuleExecution$:\n | RefreshRuntimeGlobals[\"$RefreshInterceptModuleExecution$\"];\n\ntype RefreshContext = {\n register: RefreshRuntimeGlobals[\"$RefreshReg$\"];\n signature: RefreshRuntimeGlobals[\"$RefreshSig$\"];\n};\n\ntype RefreshHelpers = RefreshRuntimeGlobals[\"$RefreshHelpers$\"];\n\ninterface TurbopackDevBaseContext extends TurbopackBaseContext {\n k: RefreshContext;\n R: ResolvePathFromModule;\n}\n\ninterface TurbopackDevContext extends TurbopackDevBaseContext {}\n\n// string encoding of a module factory (used in hmr updates)\ntype ModuleFactoryString = string;\n\ntype ModuleFactory = (\n this: Module[\"exports\"],\n context: TurbopackDevContext\n) => undefined;\n\ntype DevRuntimeParams = {\n otherChunks: ChunkData[];\n runtimeModuleIds: ModuleId[];\n};\n\ntype ChunkRegistration = [\n chunkPath: ChunkPath,\n chunkModules: ModuleFactories,\n params: DevRuntimeParams | undefined\n];\ntype ChunkList = {\n path: ChunkPath;\n chunks: ChunkData[];\n source: \"entry\" | \"dynamic\";\n};\n\nenum SourceType {\n /**\n * The module was instantiated because it was included in an evaluated chunk's\n * runtime.\n */\n Runtime = 0,\n /**\n * The module was instantiated because a parent module imported it.\n */\n Parent = 1,\n /**\n * The module was instantiated because it was included in a chunk's hot module\n * update.\n */\n Update = 2,\n}\n\ntype SourceInfo =\n | {\n type: SourceType.Runtime;\n chunkPath: ChunkPath;\n }\n | {\n type: SourceType.Parent;\n parentId: ModuleId;\n }\n | {\n type: SourceType.Update;\n parents?: ModuleId[];\n };\n\ninterface RuntimeBackend {\n registerChunk: (chunkPath: ChunkPath, params?: DevRuntimeParams) => void;\n loadChunk: (chunkPath: ChunkPath, source: SourceInfo) => Promise;\n reloadChunk?: (chunkPath: ChunkPath) => Promise;\n unloadChunk?: (chunkPath: ChunkPath) => void;\n\n restart: () => void;\n}\n\nclass UpdateApplyError extends Error {\n name = \"UpdateApplyError\";\n\n dependencyChain: string[];\n\n constructor(message: string, dependencyChain: string[]) {\n super(message);\n this.dependencyChain = dependencyChain;\n }\n}\n\nconst moduleFactories: ModuleFactories = Object.create(null);\nconst moduleCache: ModuleCache = Object.create(null);\n/**\n * Maps module IDs to persisted data between executions of their hot module\n * implementation (`hot.data`).\n */\nconst moduleHotData: Map = new Map();\n/**\n * Maps module instances to their hot module state.\n */\nconst moduleHotState: Map = new Map();\n/**\n * Modules that call `module.hot.invalidate()` (while being updated).\n */\nconst queuedInvalidatedModules: Set = new Set();\n/**\n * Module IDs that are instantiated as part of the runtime of a chunk.\n */\nconst runtimeModules: Set = new Set();\n/**\n * Map from module ID to the chunks that contain this module.\n *\n * In HMR, we need to keep track of which modules are contained in which so\n * chunks. This is so we don't eagerly dispose of a module when it is removed\n * from chunk A, but still exists in chunk B.\n */\nconst moduleChunksMap: Map> = new Map();\n/**\n * Map from a chunk path to all modules it contains.\n */\nconst chunkModulesMap: Map> = new Map();\n/**\n * Chunk lists that contain a runtime. When these chunk lists receive an update\n * that can't be reconciled with the current state of the page, we need to\n * reload the runtime entirely.\n */\nconst runtimeChunkLists: Set = new Set();\n/**\n * Map from a chunk list to the chunk paths it contains.\n */\nconst chunkListChunksMap: Map> = new Map();\n/**\n * Map from a chunk path to the chunk lists it belongs to.\n */\nconst chunkChunkListsMap: Map> = new Map();\n\nconst availableModules: Map | true> = new Map();\n\nconst availableModuleChunks: Map | true> = new Map();\n\nasync function loadChunk(\n source: SourceInfo,\n chunkData: ChunkData\n): Promise {\n if (typeof chunkData === \"string\") {\n return loadChunkPath(source, chunkData);\n }\n\n const includedList = chunkData.included || [];\n const modulesPromises = includedList.map((included) => {\n if (moduleFactories[included]) return true;\n return availableModules.get(included);\n });\n if (modulesPromises.length > 0 && modulesPromises.every((p) => p)) {\n // When all included items are already loaded or loading, we can skip loading ourselves\n return Promise.all(modulesPromises);\n }\n\n const includedModuleChunksList = chunkData.moduleChunks || [];\n const moduleChunksPromises = includedModuleChunksList\n .map((included) => {\n // TODO(alexkirsz) Do we need this check?\n // if (moduleFactories[included]) return true;\n return availableModuleChunks.get(included);\n })\n .filter((p) => p);\n\n let promise;\n if (moduleChunksPromises.length > 0) {\n // Some module chunks are already loaded or loading.\n\n if (moduleChunksPromises.length == includedModuleChunksList.length) {\n // When all included module chunks are already loaded or loading, we can skip loading ourselves\n return Promise.all(moduleChunksPromises);\n }\n\n const moduleChunksToLoad: Set = new Set();\n for (const moduleChunk of includedModuleChunksList) {\n if (!availableModuleChunks.has(moduleChunk)) {\n moduleChunksToLoad.add(moduleChunk);\n }\n }\n\n for (const moduleChunkToLoad of moduleChunksToLoad) {\n const promise = loadChunkPath(source, moduleChunkToLoad);\n\n availableModuleChunks.set(moduleChunkToLoad, promise);\n\n moduleChunksPromises.push(promise);\n }\n\n promise = Promise.all(moduleChunksPromises);\n } else {\n promise = loadChunkPath(source, chunkData.path);\n\n // Mark all included module chunks as loading if they are not already loaded or loading.\n for (const includedModuleChunk of includedModuleChunksList) {\n if (!availableModuleChunks.has(includedModuleChunk)) {\n availableModuleChunks.set(includedModuleChunk, promise);\n }\n }\n }\n\n for (const included of includedList) {\n if (!availableModules.has(included)) {\n // It might be better to race old and new promises, but it's rare that the new promise will be faster than a request started earlier.\n // In production it's even more rare, because the chunk optimization tries to deduplicate modules anyway.\n availableModules.set(included, promise);\n }\n }\n\n return promise;\n}\n\nasync function loadChunkPath(\n source: SourceInfo,\n chunkPath: ChunkPath\n): Promise {\n try {\n await BACKEND.loadChunk(chunkPath, source);\n } catch (error) {\n let loadReason;\n switch (source.type) {\n case SourceType.Runtime:\n loadReason = `as a runtime dependency of chunk ${source.chunkPath}`;\n break;\n case SourceType.Parent:\n loadReason = `from module ${source.parentId}`;\n break;\n case SourceType.Update:\n loadReason = \"from an HMR update\";\n break;\n }\n throw new Error(\n `Failed to load chunk ${chunkPath} ${loadReason}${\n error ? `: ${error}` : \"\"\n }`,\n error\n ? {\n cause: error,\n }\n : undefined\n );\n }\n}\n\n/**\n * Returns an absolute url to an asset.\n */\nfunction createResolvePathFromModule(\n resolver: (moduleId: string) => Exports\n): (moduleId: string) => string {\n return function resolvePathFromModule(moduleId: string): string {\n const exported = resolver(moduleId);\n return exported?.default ?? exported;\n };\n}\n\nfunction instantiateModule(id: ModuleId, source: SourceInfo): Module {\n const moduleFactory = moduleFactories[id];\n if (typeof moduleFactory !== \"function\") {\n // This can happen if modules incorrectly handle HMR disposes/updates,\n // e.g. when they keep a `setTimeout` around which still executes old code\n // and contains e.g. a `require(\"something\")` call.\n let instantiationReason;\n switch (source.type) {\n case SourceType.Runtime:\n instantiationReason = `as a runtime entry of chunk ${source.chunkPath}`;\n break;\n case SourceType.Parent:\n instantiationReason = `because it was required from module ${source.parentId}`;\n break;\n case SourceType.Update:\n instantiationReason = \"because of an HMR update\";\n break;\n }\n throw new Error(\n `Module ${id} was instantiated ${instantiationReason}, but the module factory is not available. It might have been deleted in an HMR update.`\n );\n }\n\n const hotData = moduleHotData.get(id)!;\n const { hot, hotState } = createModuleHot(id, hotData);\n\n let parents: ModuleId[];\n switch (source.type) {\n case SourceType.Runtime:\n runtimeModules.add(id);\n parents = [];\n break;\n case SourceType.Parent:\n // No need to add this module as a child of the parent module here, this\n // has already been taken care of in `getOrInstantiateModuleFromParent`.\n parents = [source.parentId];\n break;\n case SourceType.Update:\n parents = source.parents || [];\n break;\n }\n const module: Module = {\n exports: {},\n error: undefined,\n loaded: false,\n id,\n parents,\n children: [],\n namespaceObject: undefined,\n hot,\n };\n\n moduleCache[id] = module;\n moduleHotState.set(module, hotState);\n\n // NOTE(alexkirsz) This can fail when the module encounters a runtime error.\n try {\n const sourceInfo: SourceInfo = { type: SourceType.Parent, parentId: id };\n\n runModuleExecutionHooks(module, (refresh) => {\n const r = commonJsRequire.bind(null, module);\n moduleFactory.call(\n module.exports,\n augmentContext({\n a: asyncModule.bind(null, module),\n e: module.exports,\n r: commonJsRequire.bind(null, module),\n t: runtimeRequire,\n f: moduleContext,\n i: esmImport.bind(null, module),\n s: esmExport.bind(null, module, module.exports),\n j: dynamicExport.bind(null, module, module.exports),\n v: exportValue.bind(null, module),\n n: exportNamespace.bind(null, module),\n m: module,\n c: moduleCache,\n M: moduleFactories,\n l: loadChunk.bind(null, sourceInfo),\n w: loadWebAssembly.bind(null, sourceInfo),\n u: loadWebAssemblyModule.bind(null, sourceInfo),\n g: globalThis,\n U: relativeURL,\n k: refresh,\n R: createResolvePathFromModule(r),\n __dirname: module.id.replace(/(^|\\/)\\/+$/, \"\"),\n })\n );\n });\n } catch (error) {\n module.error = error as any;\n throw error;\n }\n\n module.loaded = true;\n if (module.namespaceObject && module.exports !== module.namespaceObject) {\n // in case of a circular dependency: cjs1 -> esm2 -> cjs1\n interopEsm(module.exports, module.namespaceObject);\n }\n\n return module;\n}\n\n/**\n * NOTE(alexkirsz) Webpack has a \"module execution\" interception hook that\n * Next.js' React Refresh runtime hooks into to add module context to the\n * refresh registry.\n */\nfunction runModuleExecutionHooks(\n module: Module,\n executeModule: (ctx: RefreshContext) => void\n) {\n const cleanupReactRefreshIntercept =\n typeof globalThis.$RefreshInterceptModuleExecution$ === \"function\"\n ? globalThis.$RefreshInterceptModuleExecution$(module.id)\n : () => {};\n\n try {\n executeModule({\n register: globalThis.$RefreshReg$,\n signature: globalThis.$RefreshSig$,\n });\n\n if (\"$RefreshHelpers$\" in globalThis) {\n // This pattern can also be used to register the exports of\n // a module with the React Refresh runtime.\n registerExportsAndSetupBoundaryForReactRefresh(\n module,\n globalThis.$RefreshHelpers$\n );\n }\n } catch (e) {\n throw e;\n } finally {\n // Always cleanup the intercept, even if module execution failed.\n cleanupReactRefreshIntercept();\n }\n}\n\n/**\n * Retrieves a module from the cache, or instantiate it if it is not cached.\n */\nconst getOrInstantiateModuleFromParent: GetOrInstantiateModuleFromParent = (\n id,\n sourceModule\n) => {\n if (!sourceModule.hot.active) {\n console.warn(\n `Unexpected import of module ${id} from module ${sourceModule.id}, which was deleted by an HMR update`\n );\n }\n\n const module = moduleCache[id];\n\n if (sourceModule.children.indexOf(id) === -1) {\n sourceModule.children.push(id);\n }\n\n if (module) {\n if (module.parents.indexOf(sourceModule.id) === -1) {\n module.parents.push(sourceModule.id);\n }\n\n return module;\n }\n\n return instantiateModule(id, {\n type: SourceType.Parent,\n parentId: sourceModule.id,\n });\n};\n\n/**\n * This is adapted from https://github.com/vercel/next.js/blob/3466862d9dc9c8bb3131712134d38757b918d1c0/packages/react-refresh-utils/internal/ReactRefreshModule.runtime.ts\n */\nfunction registerExportsAndSetupBoundaryForReactRefresh(\n module: Module,\n helpers: RefreshHelpers\n) {\n const currentExports = module.exports;\n const prevExports = module.hot.data.prevExports ?? null;\n\n helpers.registerExportsForReactRefresh(currentExports, module.id);\n\n // A module can be accepted automatically based on its exports, e.g. when\n // it is a Refresh Boundary.\n if (helpers.isReactRefreshBoundary(currentExports)) {\n // Save the previous exports on update, so we can compare the boundary\n // signatures.\n module.hot.dispose((data) => {\n data.prevExports = currentExports;\n });\n // Unconditionally accept an update to this module, we'll check if it's\n // still a Refresh Boundary later.\n module.hot.accept();\n\n // This field is set when the previous version of this module was a\n // Refresh Boundary, letting us know we need to check for invalidation or\n // enqueue an update.\n if (prevExports !== null) {\n // A boundary can become ineligible if its exports are incompatible\n // with the previous exports.\n //\n // For example, if you add/remove/change exports, we'll want to\n // re-execute the importing modules, and force those components to\n // re-render. Similarly, if you convert a class component to a\n // function, we want to invalidate the boundary.\n if (\n helpers.shouldInvalidateReactRefreshBoundary(\n helpers.getRefreshBoundarySignature(prevExports),\n helpers.getRefreshBoundarySignature(currentExports)\n )\n ) {\n module.hot.invalidate();\n } else {\n helpers.scheduleUpdate();\n }\n }\n } else {\n // Since we just executed the code for the module, it's possible that the\n // new exports made it ineligible for being a boundary.\n // We only care about the case when we were _previously_ a boundary,\n // because we already accepted this update (accidental side effect).\n const isNoLongerABoundary = prevExports !== null;\n if (isNoLongerABoundary) {\n module.hot.invalidate();\n }\n }\n}\n\nfunction formatDependencyChain(dependencyChain: ModuleId[]): string {\n return `Dependency chain: ${dependencyChain.join(\" -> \")}`;\n}\n\nfunction computeOutdatedModules(\n added: Map,\n modified: Map\n): {\n outdatedModules: Set;\n newModuleFactories: Map;\n} {\n const newModuleFactories = new Map();\n\n for (const [moduleId, entry] of added) {\n if (entry != null) {\n newModuleFactories.set(moduleId, _eval(entry));\n }\n }\n\n const outdatedModules = computedInvalidatedModules(modified.keys());\n\n for (const [moduleId, entry] of modified) {\n newModuleFactories.set(moduleId, _eval(entry));\n }\n\n return { outdatedModules, newModuleFactories };\n}\n\nfunction computedInvalidatedModules(\n invalidated: Iterable\n): Set {\n const outdatedModules = new Set();\n\n for (const moduleId of invalidated) {\n const effect = getAffectedModuleEffects(moduleId);\n\n switch (effect.type) {\n case \"unaccepted\":\n throw new UpdateApplyError(\n `cannot apply update: unaccepted module. ${formatDependencyChain(\n effect.dependencyChain\n )}.`,\n effect.dependencyChain\n );\n case \"self-declined\":\n throw new UpdateApplyError(\n `cannot apply update: self-declined module. ${formatDependencyChain(\n effect.dependencyChain\n )}.`,\n effect.dependencyChain\n );\n case \"accepted\":\n for (const outdatedModuleId of effect.outdatedModules) {\n outdatedModules.add(outdatedModuleId);\n }\n break;\n // TODO(alexkirsz) Dependencies: handle dependencies effects.\n }\n }\n\n return outdatedModules;\n}\n\nfunction computeOutdatedSelfAcceptedModules(\n outdatedModules: Iterable\n): { moduleId: ModuleId; errorHandler: true | Function }[] {\n const outdatedSelfAcceptedModules = [];\n for (const moduleId of outdatedModules) {\n const module = moduleCache[moduleId];\n const hotState = moduleHotState.get(module)!;\n if (module && hotState.selfAccepted && !hotState.selfInvalidated) {\n outdatedSelfAcceptedModules.push({\n moduleId,\n errorHandler: hotState.selfAccepted,\n });\n }\n }\n return outdatedSelfAcceptedModules;\n}\n\n/**\n * Adds, deletes, and moves modules between chunks. This must happen before the\n * dispose phase as it needs to know which modules were removed from all chunks,\n * which we can only compute *after* taking care of added and moved modules.\n */\nfunction updateChunksPhase(\n chunksAddedModules: Map>,\n chunksDeletedModules: Map>\n): { disposedModules: Set } {\n for (const [chunkPath, addedModuleIds] of chunksAddedModules) {\n for (const moduleId of addedModuleIds) {\n addModuleToChunk(moduleId, chunkPath);\n }\n }\n\n const disposedModules: Set = new Set();\n for (const [chunkPath, addedModuleIds] of chunksDeletedModules) {\n for (const moduleId of addedModuleIds) {\n if (removeModuleFromChunk(moduleId, chunkPath)) {\n disposedModules.add(moduleId);\n }\n }\n }\n\n return { disposedModules };\n}\n\nfunction disposePhase(\n outdatedModules: Iterable,\n disposedModules: Iterable\n): { outdatedModuleParents: Map> } {\n for (const moduleId of outdatedModules) {\n disposeModule(moduleId, \"replace\");\n }\n\n for (const moduleId of disposedModules) {\n disposeModule(moduleId, \"clear\");\n }\n\n // Removing modules from the module cache is a separate step.\n // We also want to keep track of previous parents of the outdated modules.\n const outdatedModuleParents = new Map();\n for (const moduleId of outdatedModules) {\n const oldModule = moduleCache[moduleId];\n outdatedModuleParents.set(moduleId, oldModule?.parents);\n delete moduleCache[moduleId];\n }\n\n // TODO(alexkirsz) Dependencies: remove outdated dependency from module\n // children.\n\n return { outdatedModuleParents };\n}\n\n/**\n * Disposes of an instance of a module.\n *\n * Returns the persistent hot data that should be kept for the next module\n * instance.\n *\n * NOTE: mode = \"replace\" will not remove modules from the moduleCache.\n * This must be done in a separate step afterwards.\n * This is important because all modules need to be disposed to update the\n * parent/child relationships before they are actually removed from the moduleCache.\n * If this was done in this method, the following disposeModule calls won't find\n * the module from the module id in the cache.\n */\nfunction disposeModule(moduleId: ModuleId, mode: \"clear\" | \"replace\") {\n const module = moduleCache[moduleId];\n if (!module) {\n return;\n }\n\n const hotState = moduleHotState.get(module)!;\n const data = {};\n\n // Run the `hot.dispose` handler, if any, passing in the persistent\n // `hot.data` object.\n for (const disposeHandler of hotState.disposeHandlers) {\n disposeHandler(data);\n }\n\n // This used to warn in `getOrInstantiateModuleFromParent` when a disposed\n // module is still importing other modules.\n module.hot.active = false;\n\n moduleHotState.delete(module);\n\n // TODO(alexkirsz) Dependencies: delete the module from outdated deps.\n\n // Remove the disposed module from its children's parent list.\n // It will be added back once the module re-instantiates and imports its\n // children again.\n for (const childId of module.children) {\n const child = moduleCache[childId];\n if (!child) {\n continue;\n }\n\n const idx = child.parents.indexOf(module.id);\n if (idx >= 0) {\n child.parents.splice(idx, 1);\n }\n }\n\n switch (mode) {\n case \"clear\":\n delete moduleCache[module.id];\n moduleHotData.delete(module.id);\n break;\n case \"replace\":\n moduleHotData.set(module.id, data);\n break;\n default:\n invariant(mode, (mode) => `invalid mode: ${mode}`);\n }\n}\n\nfunction applyPhase(\n outdatedSelfAcceptedModules: {\n moduleId: ModuleId;\n errorHandler: true | Function;\n }[],\n newModuleFactories: Map,\n outdatedModuleParents: Map>,\n reportError: (err: any) => void\n) {\n // Update module factories.\n for (const [moduleId, factory] of newModuleFactories.entries()) {\n moduleFactories[moduleId] = factory;\n }\n\n // TODO(alexkirsz) Run new runtime entries here.\n\n // TODO(alexkirsz) Dependencies: call accept handlers for outdated deps.\n\n // Re-instantiate all outdated self-accepted modules.\n for (const { moduleId, errorHandler } of outdatedSelfAcceptedModules) {\n try {\n instantiateModule(moduleId, {\n type: SourceType.Update,\n parents: outdatedModuleParents.get(moduleId),\n });\n } catch (err) {\n if (typeof errorHandler === \"function\") {\n try {\n errorHandler(err, { moduleId, module: moduleCache[moduleId] });\n } catch (err2) {\n reportError(err2);\n reportError(err);\n }\n } else {\n reportError(err);\n }\n }\n }\n}\n\n/**\n * Utility function to ensure all variants of an enum are handled.\n */\nfunction invariant(never: never, computeMessage: (arg: any) => string): never {\n throw new Error(`Invariant: ${computeMessage(never)}`);\n}\n\nfunction applyUpdate(update: PartialUpdate) {\n switch (update.type) {\n case \"ChunkListUpdate\":\n applyChunkListUpdate(update);\n break;\n default:\n invariant(update, (update) => `Unknown update type: ${update.type}`);\n }\n}\n\nfunction applyChunkListUpdate(update: ChunkListUpdate) {\n if (update.merged != null) {\n for (const merged of update.merged) {\n switch (merged.type) {\n case \"EcmascriptMergedUpdate\":\n applyEcmascriptMergedUpdate(merged);\n break;\n default:\n invariant(merged, (merged) => `Unknown merged type: ${merged.type}`);\n }\n }\n }\n\n if (update.chunks != null) {\n for (const [chunkPath, chunkUpdate] of Object.entries(update.chunks)) {\n switch (chunkUpdate.type) {\n case \"added\":\n BACKEND.loadChunk(chunkPath, { type: SourceType.Update });\n break;\n case \"total\":\n BACKEND.reloadChunk?.(chunkPath);\n break;\n case \"deleted\":\n BACKEND.unloadChunk?.(chunkPath);\n break;\n case \"partial\":\n invariant(\n chunkUpdate.instruction,\n (instruction) =>\n `Unknown partial instruction: ${JSON.stringify(instruction)}.`\n );\n default:\n invariant(\n chunkUpdate,\n (chunkUpdate) => `Unknown chunk update type: ${chunkUpdate.type}`\n );\n }\n }\n }\n}\n\nfunction applyEcmascriptMergedUpdate(update: EcmascriptMergedUpdate) {\n const { entries = {}, chunks = {} } = update;\n const { added, modified, chunksAdded, chunksDeleted } = computeChangedModules(\n entries,\n chunks\n );\n const { outdatedModules, newModuleFactories } = computeOutdatedModules(\n added,\n modified\n );\n const { disposedModules } = updateChunksPhase(chunksAdded, chunksDeleted);\n\n applyInternal(outdatedModules, disposedModules, newModuleFactories);\n}\n\nfunction applyInvalidatedModules(outdatedModules: Set) {\n if (queuedInvalidatedModules.size > 0) {\n computedInvalidatedModules(queuedInvalidatedModules).forEach((moduleId) => {\n outdatedModules.add(moduleId);\n });\n\n queuedInvalidatedModules.clear();\n }\n\n return outdatedModules;\n}\n\nfunction applyInternal(\n outdatedModules: Set,\n disposedModules: Iterable,\n newModuleFactories: Map\n) {\n outdatedModules = applyInvalidatedModules(outdatedModules);\n\n const outdatedSelfAcceptedModules =\n computeOutdatedSelfAcceptedModules(outdatedModules);\n\n const { outdatedModuleParents } = disposePhase(\n outdatedModules,\n disposedModules\n );\n\n // we want to continue on error and only throw the error after we tried applying all updates\n let error: any;\n\n function reportError(err: any) {\n if (!error) error = err;\n }\n\n applyPhase(\n outdatedSelfAcceptedModules,\n newModuleFactories,\n outdatedModuleParents,\n reportError\n );\n\n if (error) {\n throw error;\n }\n\n if (queuedInvalidatedModules.size > 0) {\n applyInternal(new Set(), [], new Map());\n }\n}\n\nfunction computeChangedModules(\n entries: Record,\n updates: Record\n): {\n added: Map;\n modified: Map;\n deleted: Set;\n chunksAdded: Map>;\n chunksDeleted: Map>;\n} {\n const chunksAdded = new Map();\n const chunksDeleted = new Map();\n const added: Map = new Map();\n const modified = new Map();\n const deleted: Set = new Set();\n\n for (const [chunkPath, mergedChunkUpdate] of Object.entries(updates)) {\n switch (mergedChunkUpdate.type) {\n case \"added\": {\n const updateAdded = new Set(mergedChunkUpdate.modules);\n for (const moduleId of updateAdded) {\n added.set(moduleId, entries[moduleId]);\n }\n chunksAdded.set(chunkPath, updateAdded);\n break;\n }\n case \"deleted\": {\n // We could also use `mergedChunkUpdate.modules` here.\n const updateDeleted = new Set(chunkModulesMap.get(chunkPath));\n for (const moduleId of updateDeleted) {\n deleted.add(moduleId);\n }\n chunksDeleted.set(chunkPath, updateDeleted);\n break;\n }\n case \"partial\": {\n const updateAdded = new Set(mergedChunkUpdate.added);\n const updateDeleted = new Set(mergedChunkUpdate.deleted);\n for (const moduleId of updateAdded) {\n added.set(moduleId, entries[moduleId]);\n }\n for (const moduleId of updateDeleted) {\n deleted.add(moduleId);\n }\n chunksAdded.set(chunkPath, updateAdded);\n chunksDeleted.set(chunkPath, updateDeleted);\n break;\n }\n default:\n invariant(\n mergedChunkUpdate,\n (mergedChunkUpdate) =>\n `Unknown merged chunk update type: ${mergedChunkUpdate.type}`\n );\n }\n }\n\n // If a module was added from one chunk and deleted from another in the same update,\n // consider it to be modified, as it means the module was moved from one chunk to another\n // AND has new code in a single update.\n for (const moduleId of added.keys()) {\n if (deleted.has(moduleId)) {\n added.delete(moduleId);\n deleted.delete(moduleId);\n }\n }\n\n for (const [moduleId, entry] of Object.entries(entries)) {\n // Modules that haven't been added to any chunk but have new code are considered\n // to be modified.\n // This needs to be under the previous loop, as we need it to get rid of modules\n // that were added and deleted in the same update.\n if (!added.has(moduleId)) {\n modified.set(moduleId, entry);\n }\n }\n\n return { added, deleted, modified, chunksAdded, chunksDeleted };\n}\n\ntype ModuleEffect =\n | {\n type: \"unaccepted\";\n dependencyChain: ModuleId[];\n }\n | {\n type: \"self-declined\";\n dependencyChain: ModuleId[];\n moduleId: ModuleId;\n }\n | {\n type: \"accepted\";\n moduleId: ModuleId;\n outdatedModules: Set;\n };\n\nfunction getAffectedModuleEffects(moduleId: ModuleId): ModuleEffect {\n const outdatedModules: Set = new Set();\n\n type QueueItem = { moduleId?: ModuleId; dependencyChain: ModuleId[] };\n\n const queue: QueueItem[] = [\n {\n moduleId,\n dependencyChain: [],\n },\n ];\n\n let nextItem;\n while ((nextItem = queue.shift())) {\n const { moduleId, dependencyChain } = nextItem;\n\n if (moduleId != null) {\n outdatedModules.add(moduleId);\n }\n\n // We've arrived at the runtime of the chunk, which means that nothing\n // else above can accept this update.\n if (moduleId === undefined) {\n return {\n type: \"unaccepted\",\n dependencyChain,\n };\n }\n\n const module = moduleCache[moduleId];\n const hotState = moduleHotState.get(module)!;\n\n if (\n // The module is not in the cache. Since this is a \"modified\" update,\n // it means that the module was never instantiated before.\n !module || // The module accepted itself without invalidating globalThis.\n // TODO is that right?\n (hotState.selfAccepted && !hotState.selfInvalidated)\n ) {\n continue;\n }\n\n if (hotState.selfDeclined) {\n return {\n type: \"self-declined\",\n dependencyChain,\n moduleId,\n };\n }\n\n if (runtimeModules.has(moduleId)) {\n queue.push({\n moduleId: undefined,\n dependencyChain: [...dependencyChain, moduleId],\n });\n continue;\n }\n\n for (const parentId of module.parents) {\n const parent = moduleCache[parentId];\n\n if (!parent) {\n // TODO(alexkirsz) Is this even possible?\n continue;\n }\n\n // TODO(alexkirsz) Dependencies: check accepted and declined\n // dependencies here.\n\n queue.push({\n moduleId: parentId,\n dependencyChain: [...dependencyChain, moduleId],\n });\n }\n }\n\n return {\n type: \"accepted\",\n moduleId,\n outdatedModules,\n };\n}\n\nfunction handleApply(chunkListPath: ChunkPath, update: ServerMessage) {\n switch (update.type) {\n case \"partial\": {\n // This indicates that the update is can be applied to the current state of the application.\n applyUpdate(update.instruction);\n break;\n }\n case \"restart\": {\n // This indicates that there is no way to apply the update to the\n // current state of the application, and that the application must be\n // restarted.\n BACKEND.restart();\n break;\n }\n case \"notFound\": {\n // This indicates that the chunk list no longer exists: either the dynamic import which created it was removed,\n // or the page itself was deleted.\n // If it is a dynamic import, we simply discard all modules that the chunk has exclusive access to.\n // If it is a runtime chunk list, we restart the application.\n if (runtimeChunkLists.has(chunkListPath)) {\n BACKEND.restart();\n } else {\n disposeChunkList(chunkListPath);\n }\n break;\n }\n default:\n throw new Error(`Unknown update type: ${update.type}`);\n }\n}\n\nfunction createModuleHot(\n moduleId: ModuleId,\n hotData: HotData\n): { hot: Hot; hotState: HotState } {\n const hotState: HotState = {\n selfAccepted: false,\n selfDeclined: false,\n selfInvalidated: false,\n disposeHandlers: [],\n };\n\n const hot: Hot = {\n // TODO(alexkirsz) This is not defined in the HMR API. It was used to\n // decide whether to warn whenever an HMR-disposed module required other\n // modules. We might want to remove it.\n active: true,\n\n data: hotData ?? {},\n\n // TODO(alexkirsz) Support full (dep, callback, errorHandler) form.\n accept: (\n modules?: string | string[] | AcceptErrorHandler,\n _callback?: AcceptCallback,\n _errorHandler?: AcceptErrorHandler\n ) => {\n if (modules === undefined) {\n hotState.selfAccepted = true;\n } else if (typeof modules === \"function\") {\n hotState.selfAccepted = modules;\n } else {\n throw new Error(\"unsupported `accept` signature\");\n }\n },\n\n decline: (dep) => {\n if (dep === undefined) {\n hotState.selfDeclined = true;\n } else {\n throw new Error(\"unsupported `decline` signature\");\n }\n },\n\n dispose: (callback) => {\n hotState.disposeHandlers.push(callback);\n },\n\n addDisposeHandler: (callback) => {\n hotState.disposeHandlers.push(callback);\n },\n\n removeDisposeHandler: (callback) => {\n const idx = hotState.disposeHandlers.indexOf(callback);\n if (idx >= 0) {\n hotState.disposeHandlers.splice(idx, 1);\n }\n },\n\n invalidate: () => {\n hotState.selfInvalidated = true;\n queuedInvalidatedModules.add(moduleId);\n },\n\n // NOTE(alexkirsz) This is part of the management API, which we don't\n // implement, but the Next.js React Refresh runtime uses this to decide\n // whether to schedule an update.\n status: () => \"idle\",\n\n // NOTE(alexkirsz) Since we always return \"idle\" for now, these are no-ops.\n addStatusHandler: (_handler) => {},\n removeStatusHandler: (_handler) => {},\n\n // NOTE(jridgewell) Check returns the list of updated modules, but we don't\n // want the webpack code paths to ever update (the turbopack paths handle\n // this already).\n check: () => Promise.resolve(null),\n };\n\n return { hot, hotState };\n}\n\n/**\n * Adds a module to a chunk.\n */\nfunction addModuleToChunk(moduleId: ModuleId, chunkPath: ChunkPath) {\n let moduleChunks = moduleChunksMap.get(moduleId);\n if (!moduleChunks) {\n moduleChunks = new Set([chunkPath]);\n moduleChunksMap.set(moduleId, moduleChunks);\n } else {\n moduleChunks.add(chunkPath);\n }\n\n let chunkModules = chunkModulesMap.get(chunkPath);\n if (!chunkModules) {\n chunkModules = new Set([moduleId]);\n chunkModulesMap.set(chunkPath, chunkModules);\n } else {\n chunkModules.add(moduleId);\n }\n}\n\n/**\n * Returns the first chunk that included a module.\n * This is used by the Node.js backend, hence why it's marked as unused in this\n * file.\n */\nfunction getFirstModuleChunk(moduleId: ModuleId) {\n const moduleChunkPaths = moduleChunksMap.get(moduleId);\n if (moduleChunkPaths == null) {\n return null;\n }\n\n return moduleChunkPaths.values().next().value;\n}\n\n/**\n * Removes a module from a chunk.\n * Returns `true` if there are no remaining chunks including this module.\n */\nfunction removeModuleFromChunk(\n moduleId: ModuleId,\n chunkPath: ChunkPath\n): boolean {\n const moduleChunks = moduleChunksMap.get(moduleId)!;\n moduleChunks.delete(chunkPath);\n\n const chunkModules = chunkModulesMap.get(chunkPath)!;\n chunkModules.delete(moduleId);\n\n const noRemainingModules = chunkModules.size === 0;\n if (noRemainingModules) {\n chunkModulesMap.delete(chunkPath);\n }\n\n const noRemainingChunks = moduleChunks.size === 0;\n if (noRemainingChunks) {\n moduleChunksMap.delete(moduleId);\n }\n\n return noRemainingChunks;\n}\n\n/**\n * Disposes of a chunk list and its corresponding exclusive chunks.\n */\nfunction disposeChunkList(chunkListPath: ChunkPath): boolean {\n const chunkPaths = chunkListChunksMap.get(chunkListPath);\n if (chunkPaths == null) {\n return false;\n }\n chunkListChunksMap.delete(chunkListPath);\n\n for (const chunkPath of chunkPaths) {\n const chunkChunkLists = chunkChunkListsMap.get(chunkPath)!;\n chunkChunkLists.delete(chunkListPath);\n\n if (chunkChunkLists.size === 0) {\n chunkChunkListsMap.delete(chunkPath);\n disposeChunk(chunkPath);\n }\n }\n\n // We must also dispose of the chunk list's chunk itself to ensure it may\n // be reloaded properly in the future.\n BACKEND.unloadChunk?.(chunkListPath);\n\n return true;\n}\n\n/**\n * Disposes of a chunk and its corresponding exclusive modules.\n *\n * @returns Whether the chunk was disposed of.\n */\nfunction disposeChunk(chunkPath: ChunkPath): boolean {\n // This should happen whether the chunk has any modules in it or not.\n // For instance, CSS chunks have no modules in them, but they still need to be unloaded.\n BACKEND.unloadChunk?.(chunkPath);\n\n const chunkModules = chunkModulesMap.get(chunkPath);\n if (chunkModules == null) {\n return false;\n }\n chunkModules.delete(chunkPath);\n\n for (const moduleId of chunkModules) {\n const moduleChunks = moduleChunksMap.get(moduleId)!;\n moduleChunks.delete(chunkPath);\n\n const noRemainingChunks = moduleChunks.size === 0;\n if (noRemainingChunks) {\n moduleChunksMap.delete(moduleId);\n disposeModule(moduleId, \"clear\");\n availableModules.delete(moduleId);\n }\n }\n\n return true;\n}\n\n/**\n * Instantiates a runtime module.\n */\nfunction instantiateRuntimeModule(\n moduleId: ModuleId,\n chunkPath: ChunkPath\n): Module {\n return instantiateModule(moduleId, { type: SourceType.Runtime, chunkPath });\n}\n\n/**\n * Gets or instantiates a runtime module.\n */\nfunction getOrInstantiateRuntimeModule(\n moduleId: ModuleId,\n chunkPath: ChunkPath\n): Module {\n const module = moduleCache[moduleId];\n if (module) {\n if (module.error) {\n throw module.error;\n }\n return module;\n }\n\n return instantiateModule(moduleId, { type: SourceType.Runtime, chunkPath });\n}\n\n/**\n * Returns the URL relative to the origin where a chunk can be fetched from.\n */\nfunction getChunkRelativeUrl(chunkPath: ChunkPath): string {\n return `${CHUNK_BASE_PATH}${chunkPath\n .split(\"/\")\n .map((p) => encodeURIComponent(p))\n .join(\"/\")}`;\n}\n\n/**\n * Subscribes to chunk list updates from the update server and applies them.\n */\nfunction registerChunkList(\n chunkUpdateProvider: ChunkUpdateProvider,\n chunkList: ChunkList\n) {\n chunkUpdateProvider.push([\n chunkList.path,\n handleApply.bind(null, chunkList.path),\n ]);\n\n // Adding chunks to chunk lists and vice versa.\n const chunks = new Set(chunkList.chunks.map(getChunkPath));\n chunkListChunksMap.set(chunkList.path, chunks);\n for (const chunkPath of chunks) {\n let chunkChunkLists = chunkChunkListsMap.get(chunkPath);\n if (!chunkChunkLists) {\n chunkChunkLists = new Set([chunkList.path]);\n chunkChunkListsMap.set(chunkPath, chunkChunkLists);\n } else {\n chunkChunkLists.add(chunkList.path);\n }\n }\n\n if (chunkList.source === \"entry\") {\n markChunkListAsRuntime(chunkList.path);\n }\n}\n\n/**\n * Marks a chunk list as a runtime chunk list. There can be more than one\n * runtime chunk list. For instance, integration tests can have multiple chunk\n * groups loaded at runtime, each with its own chunk list.\n */\nfunction markChunkListAsRuntime(chunkListPath: ChunkPath) {\n runtimeChunkLists.add(chunkListPath);\n}\n\nfunction registerChunk([\n chunkPath,\n chunkModules,\n runtimeParams,\n]: ChunkRegistration) {\n for (const [moduleId, moduleFactory] of Object.entries(chunkModules)) {\n if (!moduleFactories[moduleId]) {\n moduleFactories[moduleId] = moduleFactory;\n }\n addModuleToChunk(moduleId, chunkPath);\n }\n\n return BACKEND.registerChunk(chunkPath, runtimeParams);\n}\n\nglobalThis.TURBOPACK_CHUNK_UPDATE_LISTENERS ??= [];\n\nconst chunkListsToRegister = globalThis.TURBOPACK_CHUNK_LISTS;\nif (Array.isArray(chunkListsToRegister)) {\n for (const chunkList of chunkListsToRegister) {\n registerChunkList(globalThis.TURBOPACK_CHUNK_UPDATE_LISTENERS, chunkList);\n }\n}\n\nglobalThis.TURBOPACK_CHUNK_LISTS = {\n push: (chunkList) => {\n registerChunkList(globalThis.TURBOPACK_CHUNK_UPDATE_LISTENERS!, chunkList);\n },\n} satisfies ChunkListProvider;\n"],"names":[],"mappings":"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"}}, + {"offset": {"line": 1331, "column": 0}, "map": {"version":3,"sources":["turbopack://[turbopack]/dev/runtime/dom/runtime-backend-dom.ts"],"sourcesContent":["/**\n * This file contains the runtime code specific to the Turbopack development\n * ECMAScript DOM runtime.\n *\n * It will be appended to the base development runtime code.\n */\n\n/// \n/// \n\ntype ChunkResolver = {\n resolved: boolean;\n resolve: () => void;\n reject: (error?: Error) => void;\n promise: Promise;\n};\n\nlet BACKEND: RuntimeBackend;\n\nfunction augmentContext(context: TurbopackDevBaseContext): TurbopackDevContext {\n return context;\n}\n\nfunction fetchWebAssembly(wasmChunkPath: ChunkPath) {\n return fetch(getChunkRelativeUrl(wasmChunkPath));\n}\n\nasync function loadWebAssembly(\n _source: SourceInfo,\n wasmChunkPath: ChunkPath,\n importsObj: WebAssembly.Imports\n): Promise {\n const req = fetchWebAssembly(wasmChunkPath);\n\n const { instance } = await WebAssembly.instantiateStreaming(req, importsObj);\n\n return instance.exports;\n}\n\nasync function loadWebAssemblyModule(\n _source: SourceInfo,\n wasmChunkPath: ChunkPath\n): Promise {\n const req = fetchWebAssembly(wasmChunkPath);\n\n return await WebAssembly.compileStreaming(req);\n}\n\n(() => {\n BACKEND = {\n async registerChunk(chunkPath, params) {\n const resolver = getOrCreateResolver(chunkPath);\n resolver.resolve();\n\n if (params == null) {\n return;\n }\n\n for (const otherChunkData of params.otherChunks) {\n const otherChunkPath = getChunkPath(otherChunkData);\n // Chunk might have started loading, so we want to avoid triggering another load.\n getOrCreateResolver(otherChunkPath);\n }\n\n // This waits for chunks to be loaded, but also marks included items as available.\n await Promise.all(\n params.otherChunks.map((otherChunkData) =>\n loadChunk({ type: SourceType.Runtime, chunkPath }, otherChunkData)\n )\n );\n\n if (params.runtimeModuleIds.length > 0) {\n for (const moduleId of params.runtimeModuleIds) {\n getOrInstantiateRuntimeModule(moduleId, chunkPath);\n }\n }\n },\n\n loadChunk(chunkPath, source) {\n return doLoadChunk(chunkPath, source);\n },\n\n unloadChunk(chunkPath) {\n deleteResolver(chunkPath);\n\n const chunkUrl = getChunkRelativeUrl(chunkPath);\n // TODO(PACK-2140): remove this once all filenames are guaranteed to be escaped.\n const decodedChunkUrl = decodeURI(chunkUrl);\n\n if (chunkPath.endsWith(\".css\")) {\n const links = document.querySelectorAll(\n `link[href=\"${chunkUrl}\"],link[href^=\"${chunkUrl}?\"],link[href=\"${decodedChunkUrl}\"],link[href^=\"${decodedChunkUrl}?\"]`\n );\n for (const link of Array.from(links)) {\n link.remove();\n }\n } else if (chunkPath.endsWith(\".js\")) {\n // Unloading a JS chunk would have no effect, as it lives in the JS\n // runtime once evaluated.\n // However, we still want to remove the script tag from the DOM to keep\n // the HTML somewhat consistent from the user's perspective.\n const scripts = document.querySelectorAll(\n `script[src=\"${chunkUrl}\"],script[src^=\"${chunkUrl}?\"],script[src=\"${decodedChunkUrl}\"],script[src^=\"${decodedChunkUrl}?\"]`\n );\n for (const script of Array.from(scripts)) {\n script.remove();\n }\n } else {\n throw new Error(`can't infer type of chunk from path ${chunkPath}`);\n }\n },\n\n reloadChunk(chunkPath) {\n return new Promise((resolve, reject) => {\n if (!chunkPath.endsWith(\".css\")) {\n reject(new Error(\"The DOM backend can only reload CSS chunks\"));\n return;\n }\n\n const chunkUrl = getChunkRelativeUrl(chunkPath);\n const decodedChunkUrl = decodeURI(chunkUrl);\n\n const previousLinks = document.querySelectorAll(\n `link[rel=stylesheet][href=\"${chunkUrl}\"],link[rel=stylesheet][href^=\"${chunkUrl}?\"],link[rel=stylesheet][href=\"${decodedChunkUrl}\"],link[rel=stylesheet][href^=\"${decodedChunkUrl}?\"]`\n );\n\n if (previousLinks.length == 0) {\n reject(new Error(`No link element found for chunk ${chunkPath}`));\n return;\n }\n\n const link = document.createElement(\"link\");\n link.rel = \"stylesheet\";\n\n if (navigator.userAgent.includes(\"Firefox\")) {\n // Firefox won't reload CSS files that were previously loaded on the current page,\n // we need to add a query param to make sure CSS is actually reloaded from the server.\n //\n // I believe this is this issue: https://bugzilla.mozilla.org/show_bug.cgi?id=1037506\n //\n // Safari has a similar issue, but only if you have a `` tag\n // pointing to the same URL as the stylesheet: https://bugs.webkit.org/show_bug.cgi?id=187726\n link.href = `${chunkUrl}?ts=${Date.now()}`;\n } else {\n link.href = chunkUrl;\n }\n\n link.onerror = () => {\n reject();\n };\n link.onload = () => {\n // First load the new CSS, then remove the old ones. This prevents visible\n // flickering that would happen in-between removing the previous CSS and\n // loading the new one.\n for (const previousLink of Array.from(previousLinks))\n previousLink.remove();\n\n // CSS chunks do not register themselves, and as such must be marked as\n // loaded instantly.\n resolve();\n };\n\n // Make sure to insert the new CSS right after the previous one, so that\n // its precedence is higher.\n previousLinks[0].parentElement!.insertBefore(\n link,\n previousLinks[0].nextSibling\n );\n });\n },\n\n restart: () => self.location.reload(),\n };\n\n /**\n * Maps chunk paths to the corresponding resolver.\n */\n const chunkResolvers: Map = new Map();\n\n function getOrCreateResolver(chunkPath: ChunkPath): ChunkResolver {\n let resolver = chunkResolvers.get(chunkPath);\n if (!resolver) {\n let resolve: () => void;\n let reject: (error?: Error) => void;\n const promise = new Promise((innerResolve, innerReject) => {\n resolve = innerResolve;\n reject = innerReject;\n });\n resolver = {\n resolved: false,\n promise,\n resolve: () => {\n resolver!.resolved = true;\n resolve();\n },\n reject: reject!,\n };\n chunkResolvers.set(chunkPath, resolver);\n }\n return resolver;\n }\n\n function deleteResolver(chunkPath: ChunkPath) {\n chunkResolvers.delete(chunkPath);\n }\n\n /**\n * Loads the given chunk, and returns a promise that resolves once the chunk\n * has been loaded.\n */\n async function doLoadChunk(chunkPath: ChunkPath, source: SourceInfo) {\n const resolver = getOrCreateResolver(chunkPath);\n if (resolver.resolved) {\n return resolver.promise;\n }\n\n if (source.type === SourceType.Runtime) {\n // We don't need to load chunks references from runtime code, as they're already\n // present in the DOM.\n\n if (chunkPath.endsWith(\".css\")) {\n // CSS chunks do not register themselves, and as such must be marked as\n // loaded instantly.\n resolver.resolve();\n }\n\n // We need to wait for JS chunks to register themselves within `registerChunk`\n // before we can start instantiating runtime modules, hence the absence of\n // `resolver.resolve()` in this branch.\n\n return resolver.promise;\n }\n\n const chunkUrl = getChunkRelativeUrl(chunkPath);\n const decodedChunkUrl = decodeURI(chunkUrl);\n\n if (chunkPath.endsWith(\".css\")) {\n const previousLinks = document.querySelectorAll(\n `link[rel=stylesheet][href=\"${chunkUrl}\"],link[rel=stylesheet][href^=\"${chunkUrl}?\"],link[rel=stylesheet][href=\"${decodedChunkUrl}\"],link[rel=stylesheet][href^=\"${decodedChunkUrl}?\"]`\n );\n if (previousLinks.length > 0) {\n // CSS chunks do not register themselves, and as such must be marked as\n // loaded instantly.\n resolver.resolve();\n } else {\n const link = document.createElement(\"link\");\n link.rel = \"stylesheet\";\n link.href = chunkUrl;\n link.onerror = () => {\n resolver.reject();\n };\n link.onload = () => {\n // CSS chunks do not register themselves, and as such must be marked as\n // loaded instantly.\n resolver.resolve();\n };\n document.body.appendChild(link);\n }\n } else if (chunkPath.endsWith(\".js\")) {\n const previousScripts = document.querySelectorAll(\n `script[src=\"${chunkUrl}\"],script[src^=\"${chunkUrl}?\"],script[src=\"${decodedChunkUrl}\"],script[src^=\"${decodedChunkUrl}?\"]`\n );\n if (previousScripts.length > 0) {\n // There is this edge where the script already failed loading, but we\n // can't detect that. The Promise will never resolve in this case.\n for (const script of Array.from(previousScripts)) {\n script.addEventListener(\"error\", () => {\n resolver.reject();\n });\n }\n } else {\n const script = document.createElement(\"script\");\n script.src = chunkUrl;\n // We'll only mark the chunk as loaded once the script has been executed,\n // which happens in `registerChunk`. Hence the absence of `resolve()` in\n // this branch.\n script.onerror = () => {\n resolver.reject();\n };\n document.body.appendChild(script);\n }\n } else {\n throw new Error(`can't infer type of chunk from path ${chunkPath}`);\n }\n\n return resolver.promise;\n }\n})();\n\nfunction _eval({ code, url, map }: EcmascriptModuleEntry): ModuleFactory {\n code += `\\n\\n//# sourceURL=${encodeURI(\n location.origin + CHUNK_BASE_PATH + url\n )}`;\n if (map)\n code += `\\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,${btoa(\n map\n )}`;\n return eval(code);\n}\n"],"names":[],"mappings":"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"}}, {"offset": {"line": 1553, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/runtime/default_dev_runtime/output/79fb1_turbopack-tests_tests_snapshot_runtime_default_dev_runtime_input_index_7e4b32.js b/crates/turbopack-tests/tests/snapshot/runtime/default_dev_runtime/output/79fb1_turbopack-tests_tests_snapshot_runtime_default_dev_runtime_input_index_7e4b32.js index 85cedf5e14c55..75c546e9ee565 100644 --- a/crates/turbopack-tests/tests/snapshot/runtime/default_dev_runtime/output/79fb1_turbopack-tests_tests_snapshot_runtime_default_dev_runtime_input_index_7e4b32.js +++ b/crates/turbopack-tests/tests/snapshot/runtime/default_dev_runtime/output/79fb1_turbopack-tests_tests_snapshot_runtime_default_dev_runtime_input_index_7e4b32.js @@ -1,6 +1,6 @@ (globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/79fb1_turbopack-tests_tests_snapshot_runtime_default_dev_runtime_input_index_7e4b32.js", { -"[project]/crates/turbopack-tests/tests/snapshot/runtime/default_dev_runtime/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__, m: module, e: exports, t: require }) { !function() { +"[project]/crates/turbopack-tests/tests/snapshot/runtime/default_dev_runtime/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { console.log("Hello, world!"); diff --git a/crates/turbopack-tests/tests/snapshot/runtime/default_dev_runtime/output/79fb1_turbopack-tests_tests_snapshot_runtime_default_dev_runtime_input_index_7e4b32.js.map b/crates/turbopack-tests/tests/snapshot/runtime/default_dev_runtime/output/79fb1_turbopack-tests_tests_snapshot_runtime_default_dev_runtime_input_index_7e4b32.js.map index 4ed9b6f3f76ac..7eb3e24b4b225 100644 --- a/crates/turbopack-tests/tests/snapshot/runtime/default_dev_runtime/output/79fb1_turbopack-tests_tests_snapshot_runtime_default_dev_runtime_input_index_7e4b32.js.map +++ b/crates/turbopack-tests/tests/snapshot/runtime/default_dev_runtime/output/79fb1_turbopack-tests_tests_snapshot_runtime_default_dev_runtime_input_index_7e4b32.js.map @@ -2,6 +2,6 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/runtime/default_dev_runtime/input/index.js"],"sourcesContent":["console.log(\"Hello, world!\");\n"],"names":[],"mappings":"AAAA,QAAQ,GAAG,CAAC"}}, + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/runtime/default_dev_runtime/input/index.js"],"sourcesContent":["console.log(\"Hello, world!\");\n"],"names":[],"mappings":"AAAA,QAAQ,GAAG,CAAC"}}, {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/styled_components/styled_components/output/crates_turbopack-tests_tests_snapshot_ededc0._.js b/crates/turbopack-tests/tests/snapshot/styled_components/styled_components/output/crates_turbopack-tests_tests_snapshot_ededc0._.js index ccc8bca696343..bcc3d05e8620b 100644 --- a/crates/turbopack-tests/tests/snapshot/styled_components/styled_components/output/crates_turbopack-tests_tests_snapshot_ededc0._.js +++ b/crates/turbopack-tests/tests/snapshot/styled_components/styled_components/output/crates_turbopack-tests_tests_snapshot_ededc0._.js @@ -1,6 +1,6 @@ (globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_ededc0._.js", { -"[project]/crates/turbopack-tests/tests/snapshot/styled_components/styled_components/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/styled_components/styled_components/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; __turbopack_esm__({}); @@ -16,7 +16,7 @@ const MyButton = __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbo console.log(MyButton); })()), -"[project]/crates/turbopack-tests/tests/snapshot/node_modules/styled-components/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__, m: module, e: exports, t: require }) { !function() { +"[project]/crates/turbopack-tests/tests/snapshot/node_modules/styled-components/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { "purposefully empty stub"; "styled-components/index.js"; diff --git a/crates/turbopack-tests/tests/snapshot/styled_components/styled_components/output/crates_turbopack-tests_tests_snapshot_ededc0._.js.map b/crates/turbopack-tests/tests/snapshot/styled_components/styled_components/output/crates_turbopack-tests_tests_snapshot_ededc0._.js.map index 01448e812c06d..237ff0b1db5de 100644 --- a/crates/turbopack-tests/tests/snapshot/styled_components/styled_components/output/crates_turbopack-tests_tests_snapshot_ededc0._.js.map +++ b/crates/turbopack-tests/tests/snapshot/styled_components/styled_components/output/crates_turbopack-tests_tests_snapshot_ededc0._.js.map @@ -2,8 +2,8 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/styled_components/styled_components/input/index.js"],"sourcesContent":["import styled from \"styled-components\";\n\nconst MyButton = styled.button`\n background: blue;\n`;\n\nconsole.log(MyButton);\n"],"names":[],"mappings":";;;;AAEA,MAAM,WAAW,4LAAA,CAAA,UAAM,CAAC,MAAM;;;EAAA,CAAC;;AAE/B,CAAC;AAED,QAAQ,GAAG,CAAC"}}, + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/styled_components/styled_components/input/index.js"],"sourcesContent":["import styled from \"styled-components\";\n\nconst MyButton = styled.button`\n background: blue;\n`;\n\nconsole.log(MyButton);\n"],"names":[],"mappings":";;;;AAEA,MAAM,WAAW,4LAAA,CAAA,UAAM,CAAC,MAAM;;;EAAA,CAAC;;AAE/B,CAAC;AAED,QAAQ,GAAG,CAAC"}}, {"offset": {"line": 16, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 20, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/node_modules/styled-components/index.js"],"sourcesContent":["\"purposefully empty stub\";\n\"styled-components/index.js\"\n"],"names":[],"mappings":"AAAA;AACA"}}, + {"offset": {"line": 20, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/node_modules/styled-components/index.js"],"sourcesContent":["\"purposefully empty stub\";\n\"styled-components/index.js\"\n"],"names":[],"mappings":"AAAA;AACA"}}, {"offset": {"line": 22, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/output/crates_turbopack-tests_tests_snapshot_9cde7b._.js b/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/output/crates_turbopack-tests_tests_snapshot_9cde7b._.js index c981b0a22e4f3..43cd9371a063c 100644 --- a/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/output/crates_turbopack-tests_tests_snapshot_9cde7b._.js +++ b/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/output/crates_turbopack-tests_tests_snapshot_9cde7b._.js @@ -1,6 +1,6 @@ (globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_9cde7b._.js", { -"[project]/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/input/packages/component/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/input/packages/component/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; __turbopack_esm__({ @@ -20,7 +20,7 @@ function MyApp() { } })()), -"[project]/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/input/packages/app/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/input/packages/app/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; __turbopack_esm__({}); @@ -32,13 +32,13 @@ var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests console.log(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$swc_transforms$2f$mono_transforms$2f$input$2f$packages$2f$component$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__["default"], __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$swc_transforms$2f$mono_transforms$2f$input$2f$node_modules$2f$third_party_component$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__["default"]); })()), -"[project]/crates/turbopack-tests/tests/snapshot/node_modules/react/jsx-dev-runtime.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__, m: module, e: exports, t: require }) { !function() { +"[project]/crates/turbopack-tests/tests/snapshot/node_modules/react/jsx-dev-runtime.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { "purposefully empty stub"; "react/jsx-dev-runtime.js"; }.call(this) }), -"[project]/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/input/node_modules/third_party_component/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/input/node_modules/third_party_component/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; __turbopack_esm__({ diff --git a/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/output/crates_turbopack-tests_tests_snapshot_9cde7b._.js.map b/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/output/crates_turbopack-tests_tests_snapshot_9cde7b._.js.map index 0f9518cf210fb..91dd73c485cfb 100644 --- a/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/output/crates_turbopack-tests_tests_snapshot_9cde7b._.js.map +++ b/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/output/crates_turbopack-tests_tests_snapshot_9cde7b._.js.map @@ -2,12 +2,12 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/input/packages/component/index.js"],"sourcesContent":["export default function MyApp() {\n return
App
;\n}\n"],"names":[],"mappings":";;;;;;AAAe,SAAS;IACtB,qBAAO,6MAAC;kBAAI;;;;;;AACd"}}, + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/input/packages/component/index.js"],"sourcesContent":["export default function MyApp() {\n return
App
;\n}\n"],"names":[],"mappings":";;;;;;AAAe,SAAS;IACtB,qBAAO,6MAAC;kBAAI;;;;;;AACd"}}, {"offset": {"line": 20, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 25, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/input/packages/app/index.js"],"sourcesContent":["import MyApp from \"component\";\nimport ThirdPartyComponent from \"third_party_component\";\n\nconsole.log(MyApp, ThirdPartyComponent);\n"],"names":[],"mappings":";;;;;;AAGA,QAAQ,GAAG,CAAC,2NAAA,CAAA,UAAK,EAAE,2OAAA,CAAA,UAAmB"}}, + {"offset": {"line": 25, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/input/packages/app/index.js"],"sourcesContent":["import MyApp from \"component\";\nimport ThirdPartyComponent from \"third_party_component\";\n\nconsole.log(MyApp, ThirdPartyComponent);\n"],"names":[],"mappings":";;;;;;AAGA,QAAQ,GAAG,CAAC,2NAAA,CAAA,UAAK,EAAE,2OAAA,CAAA,UAAmB"}}, {"offset": {"line": 32, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 36, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/node_modules/react/jsx-dev-runtime.js"],"sourcesContent":["\"purposefully empty stub\";\n\"react/jsx-dev-runtime.js\";\n"],"names":[],"mappings":"AAAA;AACA"}}, + {"offset": {"line": 36, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/node_modules/react/jsx-dev-runtime.js"],"sourcesContent":["\"purposefully empty stub\";\n\"react/jsx-dev-runtime.js\";\n"],"names":[],"mappings":"AAAA;AACA"}}, {"offset": {"line": 38, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 43, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/input/node_modules/third_party_component/index.js"],"sourcesContent":["export default function ThirdPartyComponent() {\n return
Should not be transformed
;\n}\n"],"names":[],"mappings":";;;AAAe,SAAS;IACtB,QAAQ,IAAI,yBAAyB,EAAE;AACzC"}}, + {"offset": {"line": 43, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/input/node_modules/third_party_component/index.js"],"sourcesContent":["export default function ThirdPartyComponent() {\n return
Should not be transformed
;\n}\n"],"names":[],"mappings":";;;AAAe,SAAS;IACtB,QAAQ,IAAI,yBAAyB,EAAE;AACzC"}}, {"offset": {"line": 49, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/swc_transforms/preset_env/output/crates_turbopack-tests_tests_snapshot_f8ff4e._.js b/crates/turbopack-tests/tests/snapshot/swc_transforms/preset_env/output/crates_turbopack-tests_tests_snapshot_f8ff4e._.js index 0df0c47175da4..4a5a32df086c9 100644 --- a/crates/turbopack-tests/tests/snapshot/swc_transforms/preset_env/output/crates_turbopack-tests_tests_snapshot_f8ff4e._.js +++ b/crates/turbopack-tests/tests/snapshot/swc_transforms/preset_env/output/crates_turbopack-tests_tests_snapshot_f8ff4e._.js @@ -1,6 +1,6 @@ (globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_f8ff4e._.js", { -"[project]/crates/turbopack-tests/tests/snapshot/swc_transforms/preset_env/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/swc_transforms/preset_env/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; __turbopack_esm__({}); @@ -15,7 +15,7 @@ var Foo = function Foo() { console.log(Foo, [].includes("foo")); })()), -"[project]/crates/turbopack-tests/tests/snapshot/node_modules/@swc/helpers/_/_class_call_check.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__, m: module, e: exports, t: require }) { !function() { +"[project]/crates/turbopack-tests/tests/snapshot/node_modules/@swc/helpers/_/_class_call_check.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { "purposefully empty stub"; "@swc/helpers/_/_class_call_check.js"; diff --git a/crates/turbopack-tests/tests/snapshot/swc_transforms/preset_env/output/crates_turbopack-tests_tests_snapshot_f8ff4e._.js.map b/crates/turbopack-tests/tests/snapshot/swc_transforms/preset_env/output/crates_turbopack-tests_tests_snapshot_f8ff4e._.js.map index 0edf727d09105..77af32e64bc3d 100644 --- a/crates/turbopack-tests/tests/snapshot/swc_transforms/preset_env/output/crates_turbopack-tests_tests_snapshot_f8ff4e._.js.map +++ b/crates/turbopack-tests/tests/snapshot/swc_transforms/preset_env/output/crates_turbopack-tests_tests_snapshot_f8ff4e._.js.map @@ -2,8 +2,8 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/swc_transforms/preset_env/input/index.js"],"sourcesContent":["class Foo {}\n\nconsole.log(Foo, [].includes(\"foo\"));\n"],"names":[],"mappings":";;;;;AAAA,IAAA,AAAM,MAAN,SAAM;;8NAAA;;AAEN,QAAQ,GAAG,CAAC,KAAK,EAAE,CAAC,QAAQ,CAAC"}}, + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/swc_transforms/preset_env/input/index.js"],"sourcesContent":["class Foo {}\n\nconsole.log(Foo, [].includes(\"foo\"));\n"],"names":[],"mappings":";;;;;AAAA,IAAA,AAAM,MAAN,SAAM;;8NAAA;;AAEN,QAAQ,GAAG,CAAC,KAAK,EAAE,CAAC,QAAQ,CAAC"}}, {"offset": {"line": 15, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 19, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/node_modules/@swc/helpers/_/_class_call_check.js"],"sourcesContent":["\"purposefully empty stub\";\n\"@swc/helpers/_/_class_call_check.js\";\n"],"names":[],"mappings":"AAAA;AACA"}}, + {"offset": {"line": 19, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/node_modules/@swc/helpers/_/_class_call_check.js"],"sourcesContent":["\"purposefully empty stub\";\n\"@swc/helpers/_/_class_call_check.js\";\n"],"names":[],"mappings":"AAAA;AACA"}}, {"offset": {"line": 21, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/typescript/jsconfig-baseurl/output/crates_turbopack-tests_tests_snapshot_typescript_jsconfig-baseurl_input_f8c7e6._.js b/crates/turbopack-tests/tests/snapshot/typescript/jsconfig-baseurl/output/crates_turbopack-tests_tests_snapshot_typescript_jsconfig-baseurl_input_f8c7e6._.js index 9e76622ecf170..f9bba6e911057 100644 --- a/crates/turbopack-tests/tests/snapshot/typescript/jsconfig-baseurl/output/crates_turbopack-tests_tests_snapshot_typescript_jsconfig-baseurl_input_f8c7e6._.js +++ b/crates/turbopack-tests/tests/snapshot/typescript/jsconfig-baseurl/output/crates_turbopack-tests_tests_snapshot_typescript_jsconfig-baseurl_input_f8c7e6._.js @@ -1,6 +1,6 @@ (globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_typescript_jsconfig-baseurl_input_f8c7e6._.js", { -"[project]/crates/turbopack-tests/tests/snapshot/typescript/jsconfig-baseurl/input/prop.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/typescript/jsconfig-baseurl/input/prop.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; __turbopack_esm__({ @@ -9,7 +9,7 @@ __turbopack_esm__({ const prop = 1; })()), -"[project]/crates/turbopack-tests/tests/snapshot/typescript/jsconfig-baseurl/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/typescript/jsconfig-baseurl/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; __turbopack_esm__({}); diff --git a/crates/turbopack-tests/tests/snapshot/typescript/jsconfig-baseurl/output/crates_turbopack-tests_tests_snapshot_typescript_jsconfig-baseurl_input_f8c7e6._.js.map b/crates/turbopack-tests/tests/snapshot/typescript/jsconfig-baseurl/output/crates_turbopack-tests_tests_snapshot_typescript_jsconfig-baseurl_input_f8c7e6._.js.map index 10df3af5a2762..42075eefdde27 100644 --- a/crates/turbopack-tests/tests/snapshot/typescript/jsconfig-baseurl/output/crates_turbopack-tests_tests_snapshot_typescript_jsconfig-baseurl_input_f8c7e6._.js.map +++ b/crates/turbopack-tests/tests/snapshot/typescript/jsconfig-baseurl/output/crates_turbopack-tests_tests_snapshot_typescript_jsconfig-baseurl_input_f8c7e6._.js.map @@ -2,8 +2,8 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/typescript/jsconfig-baseurl/input/prop.js"],"sourcesContent":["export const prop = 1;\n"],"names":[],"mappings":";;;AAAO,MAAM,OAAO"}}, + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/typescript/jsconfig-baseurl/input/prop.js"],"sourcesContent":["export const prop = 1;\n"],"names":[],"mappings":";;;AAAO,MAAM,OAAO"}}, {"offset": {"line": 9, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 14, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/typescript/jsconfig-baseurl/input/index.js"],"sourcesContent":["import { prop as globalFoo } from \"foo\";\nimport { prop as localFoo } from \"./foo\";\nimport { prop as atFoo } from \"@/foo\";\n\nconsole.log(globalFoo, localFoo, atFoo);\n"],"names":[],"mappings":";;;;;;AAIA,QAAQ,GAAG,CAAC,iMAAA,CAAA,OAAS,EAAE,iMAAA,CAAA,OAAQ,EAAE,iMAAA,CAAA,OAAK"}}, + {"offset": {"line": 14, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/typescript/jsconfig-baseurl/input/index.js"],"sourcesContent":["import { prop as globalFoo } from \"foo\";\nimport { prop as localFoo } from \"./foo\";\nimport { prop as atFoo } from \"@/foo\";\n\nconsole.log(globalFoo, localFoo, atFoo);\n"],"names":[],"mappings":";;;;;;AAIA,QAAQ,GAAG,CAAC,iMAAA,CAAA,OAAS,EAAE,iMAAA,CAAA,OAAQ,EAAE,iMAAA,CAAA,OAAK"}}, {"offset": {"line": 21, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-baseurl/output/crates_turbopack-tests_tests_snapshot_typescript_tsconfig-baseurl_input_7bf5e3._.js b/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-baseurl/output/crates_turbopack-tests_tests_snapshot_typescript_tsconfig-baseurl_input_7bf5e3._.js index b749f9c184409..fc86bf93f1ccd 100644 --- a/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-baseurl/output/crates_turbopack-tests_tests_snapshot_typescript_tsconfig-baseurl_input_7bf5e3._.js +++ b/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-baseurl/output/crates_turbopack-tests_tests_snapshot_typescript_tsconfig-baseurl_input_7bf5e3._.js @@ -1,6 +1,6 @@ (globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_typescript_tsconfig-baseurl_input_7bf5e3._.js", { -"[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-baseurl/input/prop.ts [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-baseurl/input/prop.ts [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; __turbopack_esm__({ @@ -9,7 +9,7 @@ __turbopack_esm__({ const prop = 1; })()), -"[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-baseurl/input/index.ts [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-baseurl/input/index.ts [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; __turbopack_esm__({}); diff --git a/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-baseurl/output/crates_turbopack-tests_tests_snapshot_typescript_tsconfig-baseurl_input_7bf5e3._.js.map b/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-baseurl/output/crates_turbopack-tests_tests_snapshot_typescript_tsconfig-baseurl_input_7bf5e3._.js.map index ae7ea7d376d23..9a6b6568bdbe8 100644 --- a/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-baseurl/output/crates_turbopack-tests_tests_snapshot_typescript_tsconfig-baseurl_input_7bf5e3._.js.map +++ b/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-baseurl/output/crates_turbopack-tests_tests_snapshot_typescript_tsconfig-baseurl_input_7bf5e3._.js.map @@ -2,8 +2,8 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-baseurl/input/prop.ts"],"sourcesContent":["export const prop = 1;\n"],"names":[],"mappings":";;;AAAO,MAAM,OAAO"}}, + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-baseurl/input/prop.ts"],"sourcesContent":["export const prop = 1;\n"],"names":[],"mappings":";;;AAAO,MAAM,OAAO"}}, {"offset": {"line": 9, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 14, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-baseurl/input/index.ts"],"sourcesContent":["import { prop as globalFoo } from \"foo\";\nimport { prop as localFoo } from \"./foo\";\nimport { prop as atFoo } from \"@/foo\";\n\nconsole.log(globalFoo, localFoo, atFoo);\n"],"names":[],"mappings":";;;;;;AAIA,QAAQ,GAAG,CAAC,iMAAA,CAAA,OAAS,EAAE,iMAAA,CAAA,OAAQ,EAAE,iMAAA,CAAA,OAAK"}}, + {"offset": {"line": 14, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-baseurl/input/index.ts"],"sourcesContent":["import { prop as globalFoo } from \"foo\";\nimport { prop as localFoo } from \"./foo\";\nimport { prop as atFoo } from \"@/foo\";\n\nconsole.log(globalFoo, localFoo, atFoo);\n"],"names":[],"mappings":";;;;;;AAIA,QAAQ,GAAG,CAAC,iMAAA,CAAA,OAAS,EAAE,iMAAA,CAAA,OAAQ,EAAE,iMAAA,CAAA,OAAK"}}, {"offset": {"line": 21, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module-full-path/output/crates_turbopack-tests_tests_snapshot_4a4ab7._.js b/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module-full-path/output/crates_turbopack-tests_tests_snapshot_4a4ab7._.js index ee34adee6bbbf..c8382f5f9afed 100644 --- a/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module-full-path/output/crates_turbopack-tests_tests_snapshot_4a4ab7._.js +++ b/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module-full-path/output/crates_turbopack-tests_tests_snapshot_4a4ab7._.js @@ -1,6 +1,6 @@ (globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_4a4ab7._.js", { -"[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module-full-path/input/index.ts [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module-full-path/input/index.ts [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; __turbopack_esm__({}); @@ -12,7 +12,7 @@ var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests console.log(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$node_modules$2f$tsconfig$2d$mod$2f$prop$2e$ts__$5b$test$5d$__$28$ecmascript$29$__["prop"], __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$node_modules$2f$tsconfig$2d$mod$2f$prop$2e$ts__$5b$test$5d$__$28$ecmascript$29$__["prop"], __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$node_modules$2f$tsconfig$2d$mod$2f$prop$2e$ts__$5b$test$5d$__$28$ecmascript$29$__["prop"]); })()), -"[project]/crates/turbopack-tests/tests/snapshot/node_modules/tsconfig-mod/prop.ts [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/node_modules/tsconfig-mod/prop.ts [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; __turbopack_esm__({ diff --git a/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module-full-path/output/crates_turbopack-tests_tests_snapshot_4a4ab7._.js.map b/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module-full-path/output/crates_turbopack-tests_tests_snapshot_4a4ab7._.js.map index 34c8db22aa0a4..4b3db24d5d025 100644 --- a/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module-full-path/output/crates_turbopack-tests_tests_snapshot_4a4ab7._.js.map +++ b/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module-full-path/output/crates_turbopack-tests_tests_snapshot_4a4ab7._.js.map @@ -2,8 +2,8 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module-full-path/input/index.ts"],"sourcesContent":["import { prop as globalFoo } from \"foo\";\nimport { prop as localFoo } from \"./foo\";\nimport { prop as atFoo } from \"@/foo\";\n\nconsole.log(globalFoo, localFoo, atFoo);\n"],"names":[],"mappings":";;;;;;AAIA,QAAQ,GAAG,CAAC,sLAAA,CAAA,OAAS,EAAE,sLAAA,CAAA,OAAQ,EAAE,sLAAA,CAAA,OAAK"}}, + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module-full-path/input/index.ts"],"sourcesContent":["import { prop as globalFoo } from \"foo\";\nimport { prop as localFoo } from \"./foo\";\nimport { prop as atFoo } from \"@/foo\";\n\nconsole.log(globalFoo, localFoo, atFoo);\n"],"names":[],"mappings":";;;;;;AAIA,QAAQ,GAAG,CAAC,sLAAA,CAAA,OAAS,EAAE,sLAAA,CAAA,OAAQ,EAAE,sLAAA,CAAA,OAAK"}}, {"offset": {"line": 12, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 17, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/node_modules/tsconfig-mod/prop.ts"],"sourcesContent":["export const prop = 1;\n"],"names":[],"mappings":";;;AAAO,MAAM,OAAO"}}, + {"offset": {"line": 17, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/node_modules/tsconfig-mod/prop.ts"],"sourcesContent":["export const prop = 1;\n"],"names":[],"mappings":";;;AAAO,MAAM,OAAO"}}, {"offset": {"line": 21, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module/output/crates_turbopack-tests_tests_snapshot_5fc419._.js b/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module/output/crates_turbopack-tests_tests_snapshot_5fc419._.js index 51327e9d888cc..fa425a6bff8ce 100644 --- a/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module/output/crates_turbopack-tests_tests_snapshot_5fc419._.js +++ b/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module/output/crates_turbopack-tests_tests_snapshot_5fc419._.js @@ -1,6 +1,6 @@ (globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_5fc419._.js", { -"[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module/input/index.ts [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module/input/index.ts [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; __turbopack_esm__({}); @@ -12,7 +12,7 @@ var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests console.log(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$node_modules$2f$tsconfig$2d$mod$2f$prop$2e$ts__$5b$test$5d$__$28$ecmascript$29$__["prop"], __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$node_modules$2f$tsconfig$2d$mod$2f$prop$2e$ts__$5b$test$5d$__$28$ecmascript$29$__["prop"], __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$node_modules$2f$tsconfig$2d$mod$2f$prop$2e$ts__$5b$test$5d$__$28$ecmascript$29$__["prop"]); })()), -"[project]/crates/turbopack-tests/tests/snapshot/node_modules/tsconfig-mod/prop.ts [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/node_modules/tsconfig-mod/prop.ts [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; __turbopack_esm__({ diff --git a/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module/output/crates_turbopack-tests_tests_snapshot_5fc419._.js.map b/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module/output/crates_turbopack-tests_tests_snapshot_5fc419._.js.map index 986ce88a105da..a09d955edfee2 100644 --- a/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module/output/crates_turbopack-tests_tests_snapshot_5fc419._.js.map +++ b/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module/output/crates_turbopack-tests_tests_snapshot_5fc419._.js.map @@ -2,8 +2,8 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module/input/index.ts"],"sourcesContent":["import { prop as globalFoo } from \"foo\";\nimport { prop as localFoo } from \"./foo\";\nimport { prop as atFoo } from \"@/foo\";\n\nconsole.log(globalFoo, localFoo, atFoo);\n"],"names":[],"mappings":";;;;;;AAIA,QAAQ,GAAG,CAAC,sLAAA,CAAA,OAAS,EAAE,sLAAA,CAAA,OAAQ,EAAE,sLAAA,CAAA,OAAK"}}, + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module/input/index.ts"],"sourcesContent":["import { prop as globalFoo } from \"foo\";\nimport { prop as localFoo } from \"./foo\";\nimport { prop as atFoo } from \"@/foo\";\n\nconsole.log(globalFoo, localFoo, atFoo);\n"],"names":[],"mappings":";;;;;;AAIA,QAAQ,GAAG,CAAC,sLAAA,CAAA,OAAS,EAAE,sLAAA,CAAA,OAAQ,EAAE,sLAAA,CAAA,OAAK"}}, {"offset": {"line": 12, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 17, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/node_modules/tsconfig-mod/prop.ts"],"sourcesContent":["export const prop = 1;\n"],"names":[],"mappings":";;;AAAO,MAAM,OAAO"}}, + {"offset": {"line": 17, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/node_modules/tsconfig-mod/prop.ts"],"sourcesContent":["export const prop = 1;\n"],"names":[],"mappings":";;;AAAO,MAAM,OAAO"}}, {"offset": {"line": 21, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/output/a587c_tests_snapshot_typescript_tsconfig-extends-relative-dir_input_d34519._.js b/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/output/a587c_tests_snapshot_typescript_tsconfig-extends-relative-dir_input_d34519._.js index bd76fc4c48b4b..f37f52cc5b0b3 100644 --- a/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/output/a587c_tests_snapshot_typescript_tsconfig-extends-relative-dir_input_d34519._.js +++ b/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/output/a587c_tests_snapshot_typescript_tsconfig-extends-relative-dir_input_d34519._.js @@ -1,6 +1,6 @@ (globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/a587c_tests_snapshot_typescript_tsconfig-extends-relative-dir_input_d34519._.js", { -"[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/input/prop.ts [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/input/prop.ts [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; __turbopack_esm__({ @@ -9,7 +9,7 @@ __turbopack_esm__({ const prop = 1; })()), -"[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/input/index.ts [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/input/index.ts [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; __turbopack_esm__({}); diff --git a/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/output/a587c_tests_snapshot_typescript_tsconfig-extends-relative-dir_input_d34519._.js.map b/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/output/a587c_tests_snapshot_typescript_tsconfig-extends-relative-dir_input_d34519._.js.map index a68c26afa1dbb..e7ac5ec2b50a1 100644 --- a/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/output/a587c_tests_snapshot_typescript_tsconfig-extends-relative-dir_input_d34519._.js.map +++ b/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/output/a587c_tests_snapshot_typescript_tsconfig-extends-relative-dir_input_d34519._.js.map @@ -2,8 +2,8 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/input/prop.ts"],"sourcesContent":["export const prop = 1;\n"],"names":[],"mappings":";;;AAAO,MAAM,OAAO"}}, + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/input/prop.ts"],"sourcesContent":["export const prop = 1;\n"],"names":[],"mappings":";;;AAAO,MAAM,OAAO"}}, {"offset": {"line": 9, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 14, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/input/index.ts"],"sourcesContent":["import { prop as globalFoo } from \"foo\";\nimport { prop as localFoo } from \"./foo\";\nimport { prop as atFoo } from \"@/foo\";\n\nconsole.log(globalFoo, localFoo, atFoo);\n"],"names":[],"mappings":";;;;;;AAIA,QAAQ,GAAG,CAAC,oNAAA,CAAA,OAAS,EAAE,oNAAA,CAAA,OAAQ,EAAE,oNAAA,CAAA,OAAK"}}, + {"offset": {"line": 14, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/input/index.ts"],"sourcesContent":["import { prop as globalFoo } from \"foo\";\nimport { prop as localFoo } from \"./foo\";\nimport { prop as atFoo } from \"@/foo\";\n\nconsole.log(globalFoo, localFoo, atFoo);\n"],"names":[],"mappings":";;;;;;AAIA,QAAQ,GAAG,CAAC,oNAAA,CAAA,OAAS,EAAE,oNAAA,CAAA,OAAQ,EAAE,oNAAA,CAAA,OAAK"}}, {"offset": {"line": 21, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-without-ext/output/a587c_tests_snapshot_typescript_tsconfig-extends-without-ext_input_69f4f4._.js b/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-without-ext/output/a587c_tests_snapshot_typescript_tsconfig-extends-without-ext_input_69f4f4._.js index 13c5eaf44a237..1928fdb5dab07 100644 --- a/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-without-ext/output/a587c_tests_snapshot_typescript_tsconfig-extends-without-ext_input_69f4f4._.js +++ b/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-without-ext/output/a587c_tests_snapshot_typescript_tsconfig-extends-without-ext_input_69f4f4._.js @@ -1,6 +1,6 @@ (globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/a587c_tests_snapshot_typescript_tsconfig-extends-without-ext_input_69f4f4._.js", { -"[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-without-ext/input/prop.ts [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-without-ext/input/prop.ts [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; __turbopack_esm__({ @@ -9,7 +9,7 @@ __turbopack_esm__({ const prop = 1; })()), -"[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-without-ext/input/index.ts [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-without-ext/input/index.ts [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; __turbopack_esm__({}); diff --git a/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-without-ext/output/a587c_tests_snapshot_typescript_tsconfig-extends-without-ext_input_69f4f4._.js.map b/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-without-ext/output/a587c_tests_snapshot_typescript_tsconfig-extends-without-ext_input_69f4f4._.js.map index 2ce0ce3bc4c05..e85ad53ffe6cc 100644 --- a/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-without-ext/output/a587c_tests_snapshot_typescript_tsconfig-extends-without-ext_input_69f4f4._.js.map +++ b/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-without-ext/output/a587c_tests_snapshot_typescript_tsconfig-extends-without-ext_input_69f4f4._.js.map @@ -2,8 +2,8 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-without-ext/input/prop.ts"],"sourcesContent":["export const prop = 1;\n"],"names":[],"mappings":";;;AAAO,MAAM,OAAO"}}, + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-without-ext/input/prop.ts"],"sourcesContent":["export const prop = 1;\n"],"names":[],"mappings":";;;AAAO,MAAM,OAAO"}}, {"offset": {"line": 9, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 14, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-without-ext/input/index.ts"],"sourcesContent":["import { prop as globalFoo } from \"foo\";\nimport { prop as localFoo } from \"./foo\";\nimport { prop as atFoo } from \"@/foo\";\n\nconsole.log(globalFoo, localFoo, atFoo);\n"],"names":[],"mappings":";;;;;;AAIA,QAAQ,GAAG,CAAC,mNAAA,CAAA,OAAS,EAAE,mNAAA,CAAA,OAAQ,EAAE,mNAAA,CAAA,OAAK"}}, + {"offset": {"line": 14, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-without-ext/input/index.ts"],"sourcesContent":["import { prop as globalFoo } from \"foo\";\nimport { prop as localFoo } from \"./foo\";\nimport { prop as atFoo } from \"@/foo\";\n\nconsole.log(globalFoo, localFoo, atFoo);\n"],"names":[],"mappings":";;;;;;AAIA,QAAQ,GAAG,CAAC,mNAAA,CAAA,OAAS,EAAE,mNAAA,CAAA,OAAQ,EAAE,mNAAA,CAAA,OAAK"}}, {"offset": {"line": 21, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends/output/crates_turbopack-tests_tests_snapshot_typescript_tsconfig-extends_input_72bd49._.js b/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends/output/crates_turbopack-tests_tests_snapshot_typescript_tsconfig-extends_input_72bd49._.js index b4d21cab42167..78d4ea7f67c22 100644 --- a/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends/output/crates_turbopack-tests_tests_snapshot_typescript_tsconfig-extends_input_72bd49._.js +++ b/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends/output/crates_turbopack-tests_tests_snapshot_typescript_tsconfig-extends_input_72bd49._.js @@ -1,6 +1,6 @@ (globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_typescript_tsconfig-extends_input_72bd49._.js", { -"[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends/input/prop.ts [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends/input/prop.ts [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; __turbopack_esm__({ @@ -9,7 +9,7 @@ __turbopack_esm__({ const prop = 1; })()), -"[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends/input/index.ts [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, k: __turbopack_refresh__ }) => (() => { +"[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends/input/index.ts [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { "use strict"; __turbopack_esm__({}); diff --git a/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends/output/crates_turbopack-tests_tests_snapshot_typescript_tsconfig-extends_input_72bd49._.js.map b/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends/output/crates_turbopack-tests_tests_snapshot_typescript_tsconfig-extends_input_72bd49._.js.map index 29c1704bc15f0..32896c3579eaa 100644 --- a/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends/output/crates_turbopack-tests_tests_snapshot_typescript_tsconfig-extends_input_72bd49._.js.map +++ b/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends/output/crates_turbopack-tests_tests_snapshot_typescript_tsconfig-extends_input_72bd49._.js.map @@ -2,8 +2,8 @@ "version": 3, "sources": [], "sections": [ - {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends/input/prop.ts"],"sourcesContent":["export const prop = 1;\n"],"names":[],"mappings":";;;AAAO,MAAM,OAAO"}}, + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends/input/prop.ts"],"sourcesContent":["export const prop = 1;\n"],"names":[],"mappings":";;;AAAO,MAAM,OAAO"}}, {"offset": {"line": 9, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, - {"offset": {"line": 14, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends/input/index.ts"],"sourcesContent":["import { prop as globalFoo } from \"foo\";\nimport { prop as localFoo } from \"./foo\";\nimport { prop as atFoo } from \"@/foo\";\n\nconsole.log(globalFoo, localFoo, atFoo);\n"],"names":[],"mappings":";;;;;;AAIA,QAAQ,GAAG,CAAC,iMAAA,CAAA,OAAS,EAAE,iMAAA,CAAA,OAAQ,EAAE,iMAAA,CAAA,OAAK"}}, + {"offset": {"line": 14, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends/input/index.ts"],"sourcesContent":["import { prop as globalFoo } from \"foo\";\nimport { prop as localFoo } from \"./foo\";\nimport { prop as atFoo } from \"@/foo\";\n\nconsole.log(globalFoo, localFoo, atFoo);\n"],"names":[],"mappings":";;;;;;AAIA,QAAQ,GAAG,CAAC,iMAAA,CAAA,OAAS,EAAE,iMAAA,CAAA,OAAQ,EAAE,iMAAA,CAAA,OAAK"}}, {"offset": {"line": 21, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack-trace-server/Cargo.toml b/crates/turbopack-trace-server/Cargo.toml index d2cba5d30aa7a..00516465c6a1c 100644 --- a/crates/turbopack-trace-server/Cargo.toml +++ b/crates/turbopack-trace-server/Cargo.toml @@ -18,9 +18,10 @@ flate2 = { version = "1.0.28" } indexmap = { workspace = true, features = ["serde"] } itertools = { workspace = true } postcard = { workspace = true } +rayon = "1" rustc-demangle = "0.1" serde = { workspace = true } serde_json = { workspace = true } +tungstenite = { version = "0.21.0" } turbopack-trace-utils = { workspace = true } -websocket = { version = "0.27.0", features = ["sync"] } zstd = { version = "0.13.0" } diff --git a/crates/turbopack-trace-server/src/lib.rs b/crates/turbopack-trace-server/src/lib.rs new file mode 100644 index 0000000000000..c6ad3db06ee51 --- /dev/null +++ b/crates/turbopack-trace-server/src/lib.rs @@ -0,0 +1,30 @@ +#![feature(iter_intersperse)] +#![feature(hash_raw_entry)] +#![feature(box_patterns)] + +use std::{path::PathBuf, sync::Arc}; + +use self::{reader::TraceReader, server::serve, store_container::StoreContainer}; + +mod bottom_up; +mod reader; +mod self_time_tree; +mod server; +mod span; +mod span_bottom_up_ref; +mod span_graph_ref; +mod span_ref; +mod store; +mod store_container; +mod u64_empty_string; +mod u64_string; +mod viewer; + +pub fn start_turbopack_trace_server(path: PathBuf) { + let store = Arc::new(StoreContainer::new()); + let reader = TraceReader::spawn(store.clone(), path); + + serve(store); + + reader.join().unwrap(); +} diff --git a/crates/turbopack-trace-server/src/main.rs b/crates/turbopack-trace-server/src/main.rs index d1c1f8fbadba6..56f4dcdcb5888 100644 --- a/crates/turbopack-trace-server/src/main.rs +++ b/crates/turbopack-trace-server/src/main.rs @@ -31,7 +31,7 @@ fn main() { let store = Arc::new(StoreContainer::new()); let reader = TraceReader::spawn(store.clone(), arg.into()); - serve(store).unwrap(); + serve(store); reader.join().unwrap(); } diff --git a/crates/turbopack-trace-server/src/reader/heaptrack.rs b/crates/turbopack-trace-server/src/reader/heaptrack.rs index a1010340d73bd..c328230fb6534 100644 --- a/crates/turbopack-trace-server/src/reader/heaptrack.rs +++ b/crates/turbopack-trace-server/src/reader/heaptrack.rs @@ -138,10 +138,7 @@ impl HeaptrackFormat { } }, trace_instruction_pointers: vec![0], - allocations: vec![AllocationInfo { - size: 0, - trace_index: 0, - }], + allocations: vec![], spans: 0, collapse_crates: env::var("COLLAPSE_CRATES") .unwrap_or_default() diff --git a/crates/turbopack-trace-server/src/reader/mod.rs b/crates/turbopack-trace-server/src/reader/mod.rs index 233712307e2b4..ff32b47337e44 100644 --- a/crates/turbopack-trace-server/src/reader/mod.rs +++ b/crates/turbopack-trace-server/src/reader/mod.rs @@ -20,6 +20,8 @@ use crate::{ store_container::StoreContainer, }; +const MIN_INITIAL_REPORT_SIZE: u64 = 100 * 1024 * 1024; + trait TraceFormat { fn read(&mut self, buffer: &[u8]) -> Result; fn stats(&self) -> String { @@ -115,17 +117,7 @@ impl TraceReader { let mut format: Option> = None; let mut current_read = 0; - let mut initial_read = { - if let Ok(pos) = file.seek(SeekFrom::End(0)) { - if pos > 100 * 1024 * 1024 { - Some(pos) - } else { - None - } - } else { - None - } - }; + let mut initial_read = { file.seek(SeekFrom::End(0)).ok() }; if file.seek(SeekFrom::Start(0)).is_err() { return false; } @@ -145,7 +137,9 @@ impl TraceReader { match file.read(&mut chunk) { Ok(bytes_read) => { if bytes_read == 0 { - if let Some(value) = self.wait_for_more_data(&mut file, &mut initial_read) { + if let Some(value) = + self.wait_for_more_data(&mut file, &mut initial_read, format.as_deref()) + { return value; } } else { @@ -220,7 +214,9 @@ impl TraceReader { } Err(err) => { if err.kind() == io::ErrorKind::UnexpectedEof { - if let Some(value) = self.wait_for_more_data(&mut file, &mut initial_read) { + if let Some(value) = + self.wait_for_more_data(&mut file, &mut initial_read, format.as_deref()) + { return value; } } else { @@ -237,12 +233,19 @@ impl TraceReader { &mut self, file: &mut TraceFile, initial_read: &mut Option, + format: Option<&dyn TraceFormat>, ) -> Option { let Ok(pos) = file.stream_position() else { return Some(true); }; if let Some(total) = initial_read.take() { - println!("Initial read completed ({} MB)", total / (1024 * 1024),); + if let Some(format) = format { + let stats = format.stats(); + println!("{}", stats); + } + if total > MIN_INITIAL_REPORT_SIZE { + println!("Initial read completed ({} MB)", total / (1024 * 1024)); + } } thread::sleep(Duration::from_millis(100)); let Ok(end) = file.seek(SeekFrom::End(0)) else { diff --git a/crates/turbopack-trace-server/src/reader/turbopack.rs b/crates/turbopack-trace-server/src/reader/turbopack.rs index 29fe0fad9b40b..f42c599edd415 100644 --- a/crates/turbopack-trace-server/src/reader/turbopack.rs +++ b/crates/turbopack-trace-server/src/reader/turbopack.rs @@ -1,5 +1,5 @@ use std::{ - collections::{HashMap, HashSet}, + collections::{hash_map::Entry, HashMap, HashSet}, sync::Arc, }; @@ -13,12 +13,21 @@ use crate::{ store_container::{StoreContainer, StoreWriteGuard}, }; +#[derive(Default)] +struct AllocationInfo { + allocations: u64, + deallocations: u64, + allocation_count: u64, + deallocation_count: u64, +} + pub struct TurbopackFormat { store: Arc, active_ids: HashMap, queued_rows: HashMap>>, outdated_spans: HashSet, thread_stacks: HashMap>, + thread_allocation_counters: HashMap, self_time_started: HashMap<(SpanIndex, u64), u64>, } @@ -30,6 +39,7 @@ impl TurbopackFormat { queued_rows: HashMap::new(), outdated_spans: HashSet::new(), thread_stacks: HashMap::new(), + thread_allocation_counters: HashMap::new(), self_time_started: HashMap::new(), } } @@ -226,6 +236,58 @@ impl TurbopackFormat { } } } + TraceRow::AllocationCounters { + ts: _, + thread_id, + allocations, + allocation_count, + deallocations, + deallocation_count, + } => { + let info = AllocationInfo { + allocations, + deallocations, + allocation_count, + deallocation_count, + }; + let mut diff = AllocationInfo::default(); + match self.thread_allocation_counters.entry(thread_id) { + Entry::Occupied(mut entry) => { + let counter = entry.get_mut(); + diff.allocations = info.allocations - counter.allocations; + diff.deallocations = info.deallocations - counter.deallocations; + diff.allocation_count = info.allocation_count - counter.allocation_count; + diff.deallocation_count = + info.deallocation_count - counter.deallocation_count; + counter.allocations = info.allocations; + counter.deallocations = info.deallocations; + counter.allocation_count = info.allocation_count; + counter.deallocation_count = info.deallocation_count; + } + Entry::Vacant(entry) => { + entry.insert(info); + } + } + let stack = self.thread_stacks.entry(thread_id).or_default(); + if let Some(&id) = stack.last() { + if diff.allocations > 0 { + store.add_allocation( + id, + diff.allocations, + diff.allocation_count, + &mut self.outdated_spans, + ); + } + if diff.deallocations > 0 { + store.add_deallocation( + id, + diff.deallocations, + diff.deallocation_count, + &mut self.outdated_spans, + ); + } + } + } } } } diff --git a/crates/turbopack-trace-server/src/server.rs b/crates/turbopack-trace-server/src/server.rs index 6d6386d53d059..dc1a898531257 100644 --- a/crates/turbopack-trace-server/src/server.rs +++ b/crates/turbopack-trace-server/src/server.rs @@ -1,20 +1,12 @@ use std::{ - net::{Shutdown, TcpStream}, - sync::{ - atomic::{AtomicBool, Ordering}, - Arc, Mutex, - }, - thread, - time::Duration, + net::{TcpListener, TcpStream}, + sync::{Arc, Mutex}, + thread::spawn, }; use anyhow::{bail, Result}; use serde::{Deserialize, Serialize}; -use websocket::{ - server::upgrade::WsUpgrade, - sync::{server::upgrade::Buffer, Server, Writer}, - OwnedMessage, -}; +use tungstenite::{accept, Message}; use crate::{ store::SpanId, @@ -76,6 +68,7 @@ pub enum ClientToServerMessage { id: SpanId, }, Ack, + CheckForMoreData, } #[derive(Serialize, Deserialize, Debug)] @@ -101,287 +94,255 @@ pub struct ViewRect { } struct ConnectionState { - writer: Writer, store: Arc, viewer: Viewer, view_rect: ViewRect, last_update_generation: usize, } -pub fn serve(store: Arc) -> Result<()> { - let mut server: websocket::server::WsServer< - websocket::server::NoTlsAcceptor, - std::net::TcpListener, - > = Server::bind("127.0.0.1:5747")?; - loop { - let Ok(connection) = server.accept() else { - continue; - }; +pub fn serve(store: Arc) { + let server = TcpListener::bind("127.0.0.1:5747").unwrap(); + for stream in server.incoming() { let store = store.clone(); - thread::spawn(move || { - fn handle_connection( - connection: WsUpgrade>, - store: Arc, - ) -> Result<()> { - let connection = match connection.accept() { - Ok(connection) => connection, - Err((connection, error)) => { - connection.shutdown(Shutdown::Both)?; - return Err(error.into()); + + spawn(move || { + let websocket = accept(stream.unwrap()).unwrap(); + if let Err(err) = handle_connection(websocket, store) { + eprintln!("Error: {:?}", err); + } + }); + } +} + +fn handle_connection( + mut websocket: tungstenite::WebSocket, + store: Arc, +) -> Result<()> { + let state = Arc::new(Mutex::new(ConnectionState { + store, + viewer: Viewer::new(), + view_rect: ViewRect { + x: 0, + y: 0, + width: 1, + height: 1, + horizontal_pixels: 1, + query: String::new(), + view_mode: "aggregated".to_string(), + value_mode: "duration".to_string(), + }, + last_update_generation: 0, + })); + let mut update_skipped = false; + let mut ready_for_update = true; + + fn send_update( + websocket: &mut tungstenite::WebSocket, + state: &mut ConnectionState, + force_send: bool, + ready_for_update: &mut bool, + update_skipped: &mut bool, + ) -> Result<()> { + if !*ready_for_update { + if force_send { + *update_skipped = true; + } + return Ok(()); + } + let store = state.store.read(); + if !force_send && state.last_update_generation == store.generation() { + return Ok(()); + } + state.last_update_generation = store.generation(); + let Update { + lines: updates, + max, + } = state.viewer.compute_update(&store, &state.view_rect); + let count = updates.len(); + for update in updates { + let message = ServerToClientMessage::ViewLine { update }; + let message = serde_json::to_string(&message).unwrap(); + websocket.send(Message::Text(message))?; + } + let message = ServerToClientMessage::ViewLinesCount { count, max }; + let message = serde_json::to_string(&message).unwrap(); + websocket.send(Message::Text(message))?; + *ready_for_update = false; + Ok(()) + } + loop { + match websocket.read()? { + Message::Frame(_frame) => {} + Message::Text(text) => { + let message: ClientToServerMessage = serde_json::from_str(&text)?; + let mut state = state.lock().unwrap(); + match message { + ClientToServerMessage::CheckForMoreData => { + send_update( + &mut websocket, + &mut state, + false, + &mut ready_for_update, + &mut update_skipped, + )?; } - }; - println!("client connected"); - let (mut reader, writer) = connection.split()?; - let state = Arc::new(Mutex::new(ConnectionState { - writer, - store, - viewer: Viewer::new(), - view_rect: ViewRect { - x: 0, - y: 0, - width: 1, - height: 1, - horizontal_pixels: 1, - query: String::new(), - view_mode: "aggregated".to_string(), - value_mode: "duration".to_string(), - }, - last_update_generation: 0, - })); - let should_shutdown = Arc::new(AtomicBool::new(false)); - let update_skipped = Arc::new(AtomicBool::new(false)); - let ready_for_update = Arc::new(AtomicBool::new(true)); - fn send_update( - state: &mut ConnectionState, - force_send: bool, - ready_for_update: &AtomicBool, - update_skipped: &AtomicBool, - ) -> Result<()> { - if !ready_for_update.load(Ordering::SeqCst) { - if force_send { - update_skipped.store(true, Ordering::SeqCst); - } - return Ok(()); + ClientToServerMessage::ViewRect { view_rect } => { + state.view_rect = view_rect; + send_update( + &mut websocket, + &mut state, + true, + &mut ready_for_update, + &mut update_skipped, + )?; } - let store = state.store.read(); - if !force_send && state.last_update_generation == store.generation() { - return Ok(()); + ClientToServerMessage::ViewMode { id, mode, inherit } => { + let (mode, sorted) = if let Some(mode) = mode.strip_suffix("-sorted") { + (mode, true) + } else { + (mode.as_str(), false) + }; + match mode { + "raw-spans" => { + state.viewer.set_view_mode( + id, + Some((ViewMode::RawSpans { sorted }, inherit)), + ); + } + "aggregated" => { + state.viewer.set_view_mode( + id, + Some((ViewMode::Aggregated { sorted }, inherit)), + ); + } + "bottom-up" => { + state.viewer.set_view_mode( + id, + Some((ViewMode::BottomUp { sorted }, inherit)), + ); + } + "aggregated-bottom-up" => { + state.viewer.set_view_mode( + id, + Some((ViewMode::AggregatedBottomUp { sorted }, inherit)), + ); + } + _ => { + bail!("unknown view mode: {}", mode) + } + } + send_update( + &mut websocket, + &mut state, + true, + &mut ready_for_update, + &mut update_skipped, + )?; } - state.last_update_generation = store.generation(); - let Update { - lines: updates, - max, - } = state.viewer.compute_update(&store, &state.view_rect); - let count = updates.len(); - for update in updates { - let message = ServerToClientMessage::ViewLine { update }; - let message = serde_json::to_string(&message).unwrap(); - state.writer.send_message(&OwnedMessage::Text(message))?; + ClientToServerMessage::ResetViewMode { id } => { + state.viewer.set_view_mode(id, None); + send_update( + &mut websocket, + &mut state, + true, + &mut ready_for_update, + &mut update_skipped, + )?; } - let message = ServerToClientMessage::ViewLinesCount { count, max }; - let message = serde_json::to_string(&message).unwrap(); - state.writer.send_message(&OwnedMessage::Text(message))?; - ready_for_update.store(false, Ordering::SeqCst); - Ok(()) - } - let inner_thread = { - let should_shutdown = should_shutdown.clone(); - let ready_for_update = ready_for_update.clone(); - let update_skipped = update_skipped.clone(); - let state = state.clone(); - thread::spawn(move || loop { - if should_shutdown.load(Ordering::SeqCst) { - return; - } - if send_update( - &mut state.lock().unwrap(), - false, - &ready_for_update, - &update_skipped, - ) - .is_err() - { - break; - } - thread::sleep(Duration::from_millis(500)); - }) - }; - loop { - match reader.recv_message()? { - OwnedMessage::Text(text) => { - let message: ClientToServerMessage = serde_json::from_str(&text)?; - let mut state = state.lock().unwrap(); - match message { - ClientToServerMessage::ViewRect { view_rect } => { - state.view_rect = view_rect; - send_update( - &mut state, - true, - &ready_for_update, - &update_skipped, - )?; + ClientToServerMessage::Query { id } => { + let message = { + let store = state.store.read(); + if let Some((span, is_graph)) = store.span(id) { + let root_start = store.root_span().start(); + let span_start = span.start() - root_start; + let span_end = span.end() - root_start; + let duration = span.corrected_total_time(); + let cpu = span.total_time(); + let allocations = span.total_allocations(); + let deallocations = span.total_deallocations(); + let allocation_count = span.total_allocation_count(); + let persistent_allocations = span.total_persistent_allocations(); + let args = span + .args() + .map(|(k, v)| (k.to_string(), v.to_string())) + .collect(); + let mut path = Vec::new(); + let mut current = span; + while let Some(parent) = current.parent() { + path.push(parent.nice_name().1.to_string()); + current = parent; } - ClientToServerMessage::ViewMode { id, mode, inherit } => { - let (mode, sorted) = - if let Some(mode) = mode.strip_suffix("-sorted") { - (mode, true) - } else { - (mode.as_str(), false) - }; - match mode { - "raw-spans" => { - state.viewer.set_view_mode( - id, - Some((ViewMode::RawSpans { sorted }, inherit)), - ); - } - "aggregated" => { - state.viewer.set_view_mode( - id, - Some((ViewMode::Aggregated { sorted }, inherit)), - ); - } - "bottom-up" => { - state.viewer.set_view_mode( - id, - Some((ViewMode::BottomUp { sorted }, inherit)), - ); - } - "aggregated-bottom-up" => { - state.viewer.set_view_mode( - id, - Some(( - ViewMode::AggregatedBottomUp { sorted }, - inherit, - )), - ); - } - _ => { - bail!("unknown view mode: {}", mode) - } - } - send_update( - &mut state, - true, - &ready_for_update, - &update_skipped, - )?; + path.reverse(); + ServerToClientMessage::QueryResult { + id, + is_graph, + start: span_start, + end: span_end, + duration, + cpu, + allocations, + deallocations, + allocation_count, + persistent_allocations, + args, + path, } - ClientToServerMessage::ResetViewMode { id } => { - state.viewer.set_view_mode(id, None); - send_update( - &mut state, - true, - &ready_for_update, - &update_skipped, - )?; - } - ClientToServerMessage::Query { id } => { - let message = { - let store = state.store.read(); - if let Some((span, is_graph)) = store.span(id) { - let root_start = store.root_span().start(); - let span_start = span.start() - root_start; - let span_end = span.end() - root_start; - let duration = span.corrected_total_time(); - let cpu = span.total_time(); - let allocations = span.total_allocations(); - let deallocations = span.total_deallocations(); - let allocation_count = span.total_allocation_count(); - let persistent_allocations = - span.total_persistent_allocations(); - let args = span - .args() - .map(|(k, v)| (k.to_string(), v.to_string())) - .collect(); - let mut path = Vec::new(); - let mut current = span; - while let Some(parent) = current.parent() { - path.push(parent.nice_name().1.to_string()); - current = parent; - } - path.reverse(); - ServerToClientMessage::QueryResult { - id, - is_graph, - start: span_start, - end: span_end, - duration, - cpu, - allocations, - deallocations, - allocation_count, - persistent_allocations, - args, - path, - } - } else { - ServerToClientMessage::QueryResult { - id, - is_graph: false, - start: 0, - end: 0, - duration: 0, - cpu: 0, - allocations: 0, - deallocations: 0, - allocation_count: 0, - persistent_allocations: 0, - args: Vec::new(), - path: Vec::new(), - } - } - }; - let message = serde_json::to_string(&message).unwrap(); - state.writer.send_message(&OwnedMessage::Text(message))?; - send_update( - &mut state, - true, - &ready_for_update, - &update_skipped, - )?; - - continue; - } - ClientToServerMessage::Ack => { - ready_for_update.store(true, Ordering::SeqCst); - if update_skipped.load(Ordering::SeqCst) { - update_skipped.store(false, Ordering::SeqCst); - send_update( - &mut state, - true, - &ready_for_update, - &update_skipped, - )?; - } + } else { + ServerToClientMessage::QueryResult { + id, + is_graph: false, + start: 0, + end: 0, + duration: 0, + cpu: 0, + allocations: 0, + deallocations: 0, + allocation_count: 0, + persistent_allocations: 0, + args: Vec::new(), + path: Vec::new(), } } - } - OwnedMessage::Binary(_) => { - // This doesn't happen - } - OwnedMessage::Close(_) => { - reader.shutdown_all()?; - should_shutdown.store(true, Ordering::SeqCst); - inner_thread.join().unwrap(); - return Ok(()); - } - OwnedMessage::Ping(d) => { - state - .lock() - .unwrap() - .writer - .send_message(&OwnedMessage::Pong(d))?; - } - OwnedMessage::Pong(_) => { - // thanks for the fish + }; + let message = serde_json::to_string(&message).unwrap(); + websocket.send(Message::Text(message))?; + send_update( + &mut websocket, + &mut state, + true, + &mut ready_for_update, + &mut update_skipped, + )?; + + continue; + } + ClientToServerMessage::Ack => { + ready_for_update = true; + if update_skipped { + update_skipped = false; + send_update( + &mut websocket, + &mut state, + true, + &mut ready_for_update, + &mut update_skipped, + )?; } } } } - if let Err(err) = handle_connection(connection, store) { - eprintln!("Error: {:?}", err); + Message::Binary(_) => { + // This doesn't happen } - }); + Message::Close(_) => { + return Ok(()); + } + Message::Ping(d) => { + websocket.send(Message::Pong(d))?; + } + Message::Pong(_) => { + // thanks for the fish + } + } } } diff --git a/crates/turbopack-trace-server/src/span_ref.rs b/crates/turbopack-trace-server/src/span_ref.rs index 7f9a9e371af3a..3efa417b4b73b 100644 --- a/crates/turbopack-trace-server/src/span_ref.rs +++ b/crates/turbopack-trace-server/src/span_ref.rs @@ -264,6 +264,7 @@ impl<'a> SpanRef<'a> { if duration == 0 { continue; } + store.set_max_self_time_lookup(*end); let concurrent_time = store.self_time_tree.lookup_range_count(*start, *end); self_time += duration * duration / concurrent_time; } diff --git a/crates/turbopack-trace-server/src/store.rs b/crates/turbopack-trace-server/src/store.rs index d7cb16d97317f..73997782e582f 100644 --- a/crates/turbopack-trace-server/src/store.rs +++ b/crates/turbopack-trace-server/src/store.rs @@ -3,7 +3,7 @@ use std::{ collections::HashSet, mem::replace, num::NonZeroUsize, - sync::OnceLock, + sync::{atomic::AtomicU64, OnceLock}, }; use crate::{ @@ -19,6 +19,7 @@ const CUT_OFF_DEPTH: u32 = 150; pub struct Store { pub(crate) spans: Vec, pub(crate) self_time_tree: SelfTimeTree, + max_self_time_lookup_time: AtomicU64, } fn new_root_span() -> Span { @@ -52,6 +53,7 @@ impl Store { Self { spans: vec![new_root_span()], self_time_tree: SelfTimeTree::new(), + max_self_time_lookup_time: AtomicU64::new(0), } } @@ -59,6 +61,7 @@ impl Store { self.spans.truncate(1); self.spans[0] = new_root_span(); self.self_time_tree = SelfTimeTree::new(); + *self.max_self_time_lookup_time.get_mut() = 0; } pub fn has_time_info(&self) -> bool { @@ -125,6 +128,23 @@ impl Store { outdated_spans.insert(span_index); } + pub fn set_max_self_time_lookup(&self, time: u64) { + let mut old = self + .max_self_time_lookup_time + .load(std::sync::atomic::Ordering::Relaxed); + while old < time { + match self.max_self_time_lookup_time.compare_exchange( + old, + time, + std::sync::atomic::Ordering::Relaxed, + std::sync::atomic::Ordering::Relaxed, + ) { + Ok(_) => break, + Err(real_old) => old = real_old, + } + } + } + fn insert_self_time( &mut self, start: u64, @@ -132,10 +152,12 @@ impl Store { span_index: SpanIndex, outdated_spans: &mut HashSet, ) { - self.self_time_tree - .for_each_in_range(start, end, |_, _, span| { - outdated_spans.insert(*span); - }); + if *self.max_self_time_lookup_time.get_mut() >= start { + self.self_time_tree + .for_each_in_range(start, end, |_, _, span| { + outdated_spans.insert(*span); + }); + } self.self_time_tree.insert(start, end, span_index); } @@ -295,6 +317,7 @@ impl Store { span.total_deallocations.take(); span.total_persistent_allocations.take(); span.total_allocation_count.take(); + span.total_span_count.take(); span.extra.take(); } diff --git a/crates/turbopack-trace-server/src/viewer.rs b/crates/turbopack-trace-server/src/viewer.rs index f4639ff95c8c3..223a17363231f 100644 --- a/crates/turbopack-trace-server/src/viewer.rs +++ b/crates/turbopack-trace-server/src/viewer.rs @@ -5,6 +5,7 @@ use std::{ use either::Either; use itertools::Itertools; +use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; use serde::{Deserialize, Serialize}; use crate::{ @@ -236,6 +237,13 @@ impl<'a> QueueItem<'a> { } } +#[derive(Debug, PartialEq, Eq)] +enum FilterMode { + SelectedItem, + Parent, + Child, +} + #[derive(Debug)] struct QueueItemWithState<'a> { item: QueueItem<'a>, @@ -243,7 +251,7 @@ struct QueueItemWithState<'a> { start: u64, placeholder: bool, view_mode: ViewMode, - filtered: bool, + filtered: Option, } struct ChildItem<'a> { @@ -263,7 +271,13 @@ impl Viewer { pub fn compute_update(&mut self, store: &Store, view_rect: &ViewRect) -> Update { let mut highlighted_spans: HashSet = HashSet::new(); + let mut highlighted_span_parents: HashSet = HashSet::new(); let search_mode = !view_rect.query.is_empty(); + let (query, focus_mode) = if let Some(query) = view_rect.query.strip_suffix('!') { + (query, true) + } else { + (view_rect.query.as_str(), false) + }; let default_view_mode = view_rect.view_mode.as_str(); let (default_view_mode, default_sorted) = default_view_mode @@ -355,12 +369,17 @@ impl Viewer { root_spans.sort_by_key(|span| span.start()); root_spans }; + let mut children = Vec::new(); let mut current = 0; let offset = root_spans .iter() .min_by_key(|span| span.start()) .map_or(0, |span| span.start()); + root_spans.par_iter().for_each(|span| { + span.max_depth(); + QueueItem::Span(*span).value(value_mode); + }); for span in root_spans { if matches!(value_mode, ValueMode::Duration) { // Move current to start if needed. @@ -374,16 +393,20 @@ impl Viewer { default_view_mode, value_mode, QueueItem::Span(span), - false, + Some(if search_mode { + FilterMode::Parent + } else { + FilterMode::SelectedItem + }), ) && search_mode { let mut has_results = false; - for mut result in span.search(&view_rect.query) { + for mut result in span.search(query) { has_results = true; highlighted_spans.insert(result.id()); while let Some(parent) = result.parent() { result = parent; - if !highlighted_spans.insert(result.id()) { + if !highlighted_span_parents.insert(result.id()) { break; } } @@ -391,11 +414,51 @@ impl Viewer { if has_results { highlighted_spans.insert(span.id()); } else { - children.last_mut().unwrap().item.filtered = true; + children.last_mut().unwrap().item.filtered = None; } } } enqueue_children(children, &mut queue); + queue.par_iter().for_each(|item| { + let QueueItem::Span(span) = item.item else { + return; + }; + let view_mode = if span.is_complete() { + item.view_mode + } else { + item.view_mode.as_spans() + }; + + match (view_mode.bottom_up(), view_mode.aggregate_children()) { + (false, false) => {} + (false, true) => { + span.graph() + .collect::>() + .par_iter() + .for_each(|event| { + value_mode.value_from_graph_event(event); + }); + } + (true, false) => { + span.bottom_up() + .collect::>() + .par_iter() + .for_each(|bu| { + bu.spans().collect::>().par_iter().for_each(|span| { + value_mode.value_from_bottom_up_span(span); + }); + }); + } + (true, true) => { + span.bottom_up() + .collect::>() + .par_iter() + .for_each(|bu| { + value_mode.value_from_bottom_up(bu); + }); + } + } + }); let mut lines: Vec>> = vec![]; @@ -412,9 +475,35 @@ impl Viewer { let width = span.value(value_mode); let secondary = span.value(value_mode.secondary()); + let skipped_by_focus = + focus_mode && matches!(filtered, Some(FilterMode::Parent) | None); + + let get_filter_mode = |span: SpanId| { + if focus_mode + && matches!(filtered, Some(FilterMode::SelectedItem | FilterMode::Child)) + { + Some(FilterMode::Child) + } else if search_mode { + if highlighted_spans.contains(&span) { + Some(FilterMode::SelectedItem) + } else if highlighted_span_parents.contains(&span) { + Some(FilterMode::Parent) + } else { + None + } + } else { + Some(FilterMode::SelectedItem) + } + }; + // compute children let mut children = Vec::new(); let mut current = start; + let child_line_index = if skipped_by_focus { + line_index + } else { + line_index + 1 + }; match &span { QueueItem::Span(span) => { let (selected_view_mode, inherit) = self @@ -439,7 +528,7 @@ impl Viewer { }; let selected_view_mode = - if search_mode && highlighted_spans.contains(&span.id()) { + if search_mode && highlighted_span_parents.contains(&span.id()) { selected_view_mode.as_spans() } else { selected_view_mode @@ -461,11 +550,11 @@ impl Viewer { &mut children, &mut current, view_rect, - line_index + 1, + child_line_index, view_mode, value_mode, QueueItem::SpanBottomUp(child), - false, + Some(FilterMode::SelectedItem), ); } } else { @@ -479,13 +568,12 @@ impl Viewer { Either::Right(bottom_up) }; for child in bottom_up { - let filtered = - search_mode && !highlighted_spans.contains(&child.id()); + let filtered = get_filter_mode(child.id()); add_child_item( &mut children, &mut current, view_rect, - line_index + 1, + child_line_index, view_mode, value_mode, QueueItem::SpanBottomUpSpan(child), @@ -502,12 +590,12 @@ impl Viewer { Either::Right(span.children()) }; for child in spans { - let filtered = search_mode && !highlighted_spans.contains(&child.id()); + let filtered = get_filter_mode(child.id()); add_child_item( &mut children, &mut current, view_rect, - line_index + 1, + child_line_index, view_mode, value_mode, QueueItem::Span(child), @@ -523,7 +611,11 @@ impl Viewer { Either::Right(span.graph()) }; for event in events { - let filtered = search_mode; + let filtered = if search_mode { + None + } else { + Some(FilterMode::SelectedItem) + }; match event { SpanGraphEventRef::SelfTime { duration: _ } => {} SpanGraphEventRef::Child { graph } => { @@ -531,7 +623,7 @@ impl Viewer { &mut children, &mut current, view_rect, - line_index + 1, + child_line_index, view_mode, value_mode, QueueItem::SpanGraph(graph), @@ -570,11 +662,11 @@ impl Viewer { &mut children, &mut current, view_rect, - line_index + 1, + child_line_index, view_mode, value_mode, QueueItem::SpanBottomUp(child), - false, + Some(FilterMode::SelectedItem), ); } } else { @@ -588,13 +680,12 @@ impl Viewer { Either::Right(bottom_up) }; for child in bottom_up { - let filtered = - search_mode && !highlighted_spans.contains(&child.id()); + let filtered = get_filter_mode(child.id()); add_child_item( &mut children, &mut current, view_rect, - line_index + 1, + child_line_index, view_mode, value_mode, QueueItem::SpanBottomUpSpan(child), @@ -611,12 +702,12 @@ impl Viewer { Either::Right(span_graph.root_spans()) }; for child in spans { - let filtered = search_mode && !highlighted_spans.contains(&child.id()); + let filtered = get_filter_mode(child.id()); add_child_item( &mut children, &mut current, view_rect, - line_index + 1, + child_line_index, view_mode, value_mode, QueueItem::Span(child), @@ -633,12 +724,16 @@ impl Viewer { }; for child in events { if let SpanGraphEventRef::Child { graph } = child { - let filtered = search_mode; + let filtered = if search_mode { + None + } else { + Some(FilterMode::SelectedItem) + }; add_child_item( &mut children, &mut current, view_rect, - line_index + 1, + child_line_index, view_mode, value_mode, QueueItem::SpanGraph(graph), @@ -670,11 +765,11 @@ impl Viewer { &mut children, &mut current, view_rect, - line_index + 1, + child_line_index, view_mode, value_mode, QueueItem::SpanBottomUp(child), - false, + Some(FilterMode::SelectedItem), ); } } else { @@ -686,12 +781,12 @@ impl Viewer { Either::Right(bottom_up.spans()) }; for child in spans { - let filtered = search_mode && !highlighted_spans.contains(&child.id()); + let filtered = get_filter_mode(child.id()); add_child_item( &mut children, &mut current, view_rect, - line_index + 1, + child_line_index, view_mode, value_mode, QueueItem::SpanBottomUpSpan(child), @@ -709,7 +804,7 @@ impl Viewer { if placeholder { let child = children .into_iter() - .max_by_key(|ChildItem { item, depth, .. }| (!item.filtered, *depth)); + .max_by_key(|ChildItem { item, depth, .. }| (item.filtered.is_some(), *depth)); if let Some(ChildItem { item: mut entry, .. }) = child @@ -718,35 +813,39 @@ impl Viewer { queue.push(entry); } - // add span to line - line.push(LineEntry { - start, - width, - secondary: 0, - ty: LineEntryType::Placeholder(filtered), - }); + if !skipped_by_focus { + // add span to line + line.push(LineEntry { + start, + width, + secondary: 0, + ty: LineEntryType::Placeholder(filtered), + }); + } } else { // add children to queue enqueue_children(children, &mut queue); - // add span to line - line.push(LineEntry { - start, - width, - secondary, - ty: match span { - QueueItem::Span(span) => LineEntryType::Span { span, filtered }, - QueueItem::SpanGraph(span_graph) => { - LineEntryType::SpanGraph(span_graph, filtered) - } - QueueItem::SpanBottomUp(bottom_up) => { - LineEntryType::SpanBottomUp(bottom_up, filtered) - } - QueueItem::SpanBottomUpSpan(bottom_up_span) => { - LineEntryType::SpanBottomUpSpan(bottom_up_span, filtered) - } - }, - }); + if !skipped_by_focus { + // add span to line + line.push(LineEntry { + start, + width, + secondary, + ty: match span { + QueueItem::Span(span) => LineEntryType::Span { span, filtered }, + QueueItem::SpanGraph(span_graph) => { + LineEntryType::SpanGraph(span_graph, filtered) + } + QueueItem::SpanBottomUp(bottom_up) => { + LineEntryType::SpanBottomUp(bottom_up, filtered) + } + QueueItem::SpanBottomUpSpan(bottom_up_span) => { + LineEntryType::SpanBottomUpSpan(bottom_up_span, filtered) + } + }, + }); + } } } @@ -765,7 +864,10 @@ impl Viewer { category: String::new(), text: String::new(), count: 1, - kind: if filtered { 11 } else { 1 }, + kind: match filtered { + Some(_) => 1, + None => 11, + }, start_in_parent: 0, end_in_parent: 0, secondary: 0, @@ -796,7 +898,10 @@ impl Viewer { category: category.to_string(), text: text.to_string(), count: 1, - kind: if filtered { 10 } else { 0 }, + kind: match filtered { + Some(_) => 0, + None => 10, + }, start_in_parent, end_in_parent, secondary: entry.secondary, @@ -811,7 +916,10 @@ impl Viewer { category: category.to_string(), text: text.to_string(), count: graph.count() as u64, - kind: if filtered { 10 } else { 0 }, + kind: match filtered { + Some(_) => 0, + None => 10, + }, start_in_parent: 0, end_in_parent: 0, secondary: entry.secondary, @@ -826,7 +934,10 @@ impl Viewer { category: category.to_string(), text: text.to_string(), count: bottom_up.count() as u64, - kind: if filtered { 12 } else { 2 }, + kind: match filtered { + Some(_) => 2, + None => 12, + }, start_in_parent: 0, end_in_parent: 0, secondary: entry.secondary, @@ -841,7 +952,10 @@ impl Viewer { category: category.to_string(), text: text.to_string(), count: 1, - kind: if filtered { 12 } else { 2 }, + kind: match filtered { + Some(_) => 2, + None => 12, + }, start_in_parent: 0, end_in_parent: 0, secondary: entry.secondary, @@ -851,9 +965,10 @@ impl Viewer { .collect(), }) .collect(); + Update { lines, - max: current, + max: max(1, current), } } } @@ -867,7 +982,7 @@ fn add_child_item<'a>( view_mode: ViewMode, value_mode: ValueMode, child: QueueItem<'a>, - filtered: bool, + filtered: Option, ) -> bool { let child_width = child.value(value_mode); let max_depth = child.max_depth(); @@ -956,9 +1071,12 @@ struct LineEntry<'a> { } enum LineEntryType<'a> { - Placeholder(bool), - Span { span: SpanRef<'a>, filtered: bool }, - SpanGraph(SpanGraphRef<'a>, bool), - SpanBottomUp(SpanBottomUpRef<'a>, bool), - SpanBottomUpSpan(SpanRef<'a>, bool), + Placeholder(Option), + Span { + span: SpanRef<'a>, + filtered: Option, + }, + SpanGraph(SpanGraphRef<'a>, Option), + SpanBottomUp(SpanBottomUpRef<'a>, Option), + SpanBottomUpSpan(SpanRef<'a>, Option), } diff --git a/crates/turbopack-trace-utils/src/raw_trace.rs b/crates/turbopack-trace-utils/src/raw_trace.rs index 627af1267a631..9e4bc5f55f8ab 100644 --- a/crates/turbopack-trace-utils/src/raw_trace.rs +++ b/crates/turbopack-trace-utils/src/raw_trace.rs @@ -5,6 +5,7 @@ use tracing::{ span, Subscriber, }; use tracing_subscriber::{registry::LookupSpan, Layer}; +use turbo_tasks_malloc::TurboMalloc; use crate::{ flavor::BufFlavor, @@ -30,24 +31,23 @@ impl LookupSpan<'a>> RawTraceLayer { } fn write(&self, data: TraceRow<'_>) { + let start = TurboMalloc::allocation_counters(); // Buffer is recycled let buf = self.trace_writer.try_get_buffer().unwrap_or_default(); let buf = postcard::serialize_with_flavor(&data, BufFlavor { buf }).unwrap(); self.trace_writer.write(buf); + TurboMalloc::reset_allocation_counters(start); } fn report_allocations(&self, ts: u64, thread_id: u64) { - let allocation_info = turbo_tasks_malloc::TurboMalloc::pop_allocations(); - if allocation_info.is_empty() { - return; - } - self.write(TraceRow::Allocation { + let allocation_counters = turbo_tasks_malloc::TurboMalloc::allocation_counters(); + self.write(TraceRow::AllocationCounters { ts, thread_id, - allocations: allocation_info.allocations as u64, - deallocations: allocation_info.deallocations as u64, - allocation_count: allocation_info.allocation_count as u64, - deallocation_count: allocation_info.deallocation_count as u64, + allocations: allocation_counters.allocations as u64, + deallocations: allocation_counters.deallocations as u64, + allocation_count: allocation_counters.allocation_count as u64, + deallocation_count: allocation_counters.deallocation_count as u64, }); } } diff --git a/crates/turbopack-trace-utils/src/tracing.rs b/crates/turbopack-trace-utils/src/tracing.rs index 0f38d654dea55..76e4ab159d297 100644 --- a/crates/turbopack-trace-utils/src/tracing.rs +++ b/crates/turbopack-trace-utils/src/tracing.rs @@ -84,6 +84,22 @@ pub enum TraceRow<'a> { /// Deallocation count deallocation_count: u64, }, + /// Data about (de)allocations per thread counters. Actual allocations can + /// be computed from the difference. + AllocationCounters { + /// Timestamp + ts: u64, + /// The thread id of the thread where allocations happend. + thread_id: u64, + /// Allocations + allocations: u64, + /// Allocation count + allocation_count: u64, + /// Deallocations + deallocations: u64, + /// Deallocation count + deallocation_count: u64, + }, } #[derive(Debug, Serialize, Deserialize)] diff --git a/crates/turbopack-wasm/src/module_asset.rs b/crates/turbopack-wasm/src/module_asset.rs index 220df74530ca5..059bbb9ca7692 100644 --- a/crates/turbopack-wasm/src/module_asset.rs +++ b/crates/turbopack-wasm/src/module_asset.rs @@ -16,8 +16,7 @@ use turbopack_core::{ use turbopack_ecmascript::{ chunk::{ EcmascriptChunkItem, EcmascriptChunkItemContent, EcmascriptChunkItemOptions, - EcmascriptChunkPlaceable, EcmascriptChunkType, EcmascriptChunkingContext, - EcmascriptExports, + EcmascriptChunkPlaceable, EcmascriptChunkType, EcmascriptExports, }, references::async_module::OptionAsyncModule, EcmascriptModuleAsset, @@ -120,13 +119,6 @@ impl ChunkableModule for WebAssemblyModuleAsset { self: Vc, chunking_context: Vc>, ) -> Result>> { - let chunking_context = - Vc::try_resolve_downcast::>(chunking_context) - .await? - .context( - "chunking context must impl EcmascriptChunkingContext to use \ - WebAssemblyModuleAsset", - )?; Ok(Vc::upcast( ModuleChunkItem { module: self, @@ -171,7 +163,7 @@ impl ResolveOrigin for WebAssemblyModuleAsset { #[turbo_tasks::value] struct ModuleChunkItem { module: Vc, - chunking_context: Vc>, + chunking_context: Vc>, } #[turbo_tasks::value_impl] @@ -217,7 +209,7 @@ impl ChunkItem for ModuleChunkItem { #[turbo_tasks::value_impl] impl EcmascriptChunkItem for ModuleChunkItem { #[turbo_tasks::function] - fn chunking_context(&self) -> Vc> { + fn chunking_context(&self) -> Vc> { self.chunking_context } diff --git a/crates/turbopack-wasm/src/raw.rs b/crates/turbopack-wasm/src/raw.rs index 8b72a7823c4a3..80013afc1dc5a 100644 --- a/crates/turbopack-wasm/src/raw.rs +++ b/crates/turbopack-wasm/src/raw.rs @@ -1,4 +1,4 @@ -use anyhow::{bail, Context, Result}; +use anyhow::{bail, Result}; use turbo_tasks::{ValueToString, Vc}; use turbopack_core::{ asset::{Asset, AssetContent}, @@ -13,7 +13,7 @@ use turbopack_core::{ use turbopack_ecmascript::{ chunk::{ EcmascriptChunkItem, EcmascriptChunkItemContent, EcmascriptChunkPlaceable, - EcmascriptChunkType, EcmascriptChunkingContext, EcmascriptExports, + EcmascriptChunkType, EcmascriptExports, }, utils::StringifyJs, }; @@ -78,13 +78,6 @@ impl ChunkableModule for RawWebAssemblyModuleAsset { self: Vc, chunking_context: Vc>, ) -> Result>> { - let chunking_context = - Vc::try_resolve_downcast::>(chunking_context) - .await? - .context( - "chunking context must impl EcmascriptChunkingContext to use \ - RawWebAssemblyModuleAsset", - )?; Ok(Vc::upcast( RawModuleChunkItem { module: self, @@ -107,7 +100,7 @@ impl EcmascriptChunkPlaceable for RawWebAssemblyModuleAsset { #[turbo_tasks::value] struct RawModuleChunkItem { module: Vc, - chunking_context: Vc>, + chunking_context: Vc>, wasm_asset: Vc, } @@ -150,7 +143,7 @@ impl ChunkItem for RawModuleChunkItem { #[turbo_tasks::value_impl] impl EcmascriptChunkItem for RawModuleChunkItem { #[turbo_tasks::function] - fn chunking_context(&self) -> Vc> { + fn chunking_context(&self) -> Vc> { self.chunking_context } diff --git a/crates/turbopack/examples/turbopack.rs b/crates/turbopack/examples/turbopack.rs index afca14caef563..f73cb1cde4162 100644 --- a/crates/turbopack/examples/turbopack.rs +++ b/crates/turbopack/examples/turbopack.rs @@ -3,19 +3,14 @@ use std::{ collections::HashMap, env::current_dir, - fs, time::{Duration, Instant}, }; use anyhow::Result; use tokio::{spawn, time::sleep}; -use turbo_tasks::{util::FormatDuration, TurboTasks, TurboTasksBackendApi, UpdateInfo, Value, Vc}; +use turbo_tasks::{util::FormatDuration, TurboTasks, UpdateInfo, Value, Vc}; use turbo_tasks_fs::{DiskFileSystem, FileSystem}; -use turbo_tasks_memory::{ - stats::{ReferenceType, Stats}, - viz::graph::{visualize_stats_tree, wrap_html}, - MemoryBackend, -}; +use turbo_tasks_memory::MemoryBackend; use turbopack::{emit_with_completion, rebase::RebasedAsset, register}; use turbopack_core::{ compile_time_info::CompileTimeInfo, @@ -94,37 +89,6 @@ async fn main() -> Result<()> { .unwrap(); loop { - println!("writing graph.html..."); - // create a graph - let mut stats = Stats::new(); - - let b = tt.backend(); - - // graph root node - stats.add_id(b, task); - - // graph tasks in cache - b.with_all_cached_tasks(|task| { - stats.add_id(b, task); - }); - - // prettify graph - stats.merge_resolve(); - - let tree = stats.treeify(ReferenceType::Child); - - // write HTML - fs::write( - "graph.html", - wrap_html(&visualize_stats_tree( - tree, - ReferenceType::Child, - tt.stats_type(), - )), - ) - .unwrap(); - println!("graph.html written"); - sleep(Duration::from_secs(10)).await; } } diff --git a/crates/turbopack/src/lib.rs b/crates/turbopack/src/lib.rs index ced532954e71e..480213a10bf53 100644 --- a/crates/turbopack/src/lib.rs +++ b/crates/turbopack/src/lib.rs @@ -43,7 +43,8 @@ use turbopack_core::{ output::OutputAsset, raw_module::RawModule, reference_type::{ - CssReferenceSubType, EcmaScriptModulesReferenceSubType, InnerAssets, ReferenceType, + CssReferenceSubType, EcmaScriptModulesReferenceSubType, ImportWithType, InnerAssets, + ReferenceType, }, resolve::{ options::ResolveOptions, origin::PlainResolveOrigin, parse::Request, resolve, ModulePart, @@ -162,14 +163,16 @@ async fn apply_module_type( if runtime_code { Vc::upcast(builder.build()) } else { + let options = options.await?; match options.tree_shaking_mode { - Some(TreeShakingMode::ModuleFragments) => { + Some(TreeShakingMode::ModuleFragments) => Vc::upcast( if let Some(part) = part { - Vc::upcast(builder.build_part(part)) + builder.build_part(part) } else { - Vc::upcast(builder.build_part(ModulePart::exports())) + builder.build_part(ModulePart::exports()) } - } + .await?, + ), Some(TreeShakingMode::ReexportsOnly) => { let side_effect_free_packages = module_asset_context.side_effect_free_packages(); @@ -471,9 +474,25 @@ async fn process_default_internal( ReferenceType::Internal(inner_assets) => Some(*inner_assets), _ => None, }; + + let mut has_type_attribute = false; + let mut current_source = source; - let mut current_module_type = None; + let mut current_module_type = match &reference_type { + ReferenceType::EcmaScriptModules(EcmaScriptModulesReferenceSubType::ImportWithType(ty)) => { + has_type_attribute = true; + + match ty { + ImportWithType::Json => Some(ModuleType::Json), + } + } + _ => None, + }; + for (i, rule) in options.await?.rules.iter().enumerate() { + if has_type_attribute && current_module_type.is_some() { + continue; + } if processed_rules.contains(&i) { continue; } diff --git a/crates/turbopack/src/module_options/mod.rs b/crates/turbopack/src/module_options/mod.rs index b49484bda57b3..fb01248ae7a2a 100644 --- a/crates/turbopack/src/module_options/mod.rs +++ b/crates/turbopack/src/module_options/mod.rs @@ -97,6 +97,7 @@ impl ModuleOptions { } } + let mut refresh = false; let mut transforms = vec![]; // Order of transforms is important. e.g. if the React transform occurs before @@ -105,6 +106,7 @@ impl ModuleOptions { // should use `before_transform_plugins`. if let Some(enable_jsx) = enable_jsx { let jsx = enable_jsx.await?; + refresh = jsx.react_refresh; transforms.push(EcmascriptInputTransform::React { development: jsx.development, @@ -119,8 +121,10 @@ impl ModuleOptions { url_rewrite_behavior: esm_url_rewrite_behavior, import_externals, ignore_dynamic_requests, + refresh, ..Default::default() }; + let ecmascript_options_vc = ecmascript_options.cell(); if let Some(env) = preset_env_versions { transforms.push(EcmascriptInputTransform::PresetEnv(env)); @@ -216,7 +220,7 @@ impl ModuleOptions { ]), vec![ModuleRuleEffect::ModuleType(ModuleType::Ecmascript { transforms: app_transforms, - options: ecmascript_options, + options: ecmascript_options_vc, })], ), ModuleRule::new_all( @@ -226,7 +230,8 @@ impl ModuleOptions { options: EcmascriptOptions { specified_module_type: SpecifiedModuleType::EcmaScript, ..ecmascript_options - }, + } + .into(), })], ), ModuleRule::new_all( @@ -236,7 +241,8 @@ impl ModuleOptions { options: EcmascriptOptions { specified_module_type: SpecifiedModuleType::CommonJs, ..ecmascript_options - }, + } + .into(), })], ), ModuleRule::new_all( @@ -245,7 +251,7 @@ impl ModuleOptions { transforms: ts_app_transforms, tsx: false, analyze_types: enable_types, - options: ecmascript_options, + options: ecmascript_options_vc, })], ), ModuleRule::new_all( @@ -254,7 +260,7 @@ impl ModuleOptions { transforms: ts_app_transforms, tsx: true, analyze_types: enable_types, - options: ecmascript_options, + options: ecmascript_options_vc, })], ), ModuleRule::new_all( @@ -266,7 +272,8 @@ impl ModuleOptions { options: EcmascriptOptions { specified_module_type: SpecifiedModuleType::EcmaScript, ..ecmascript_options - }, + } + .into(), })], ), ModuleRule::new_all( @@ -278,7 +285,8 @@ impl ModuleOptions { options: EcmascriptOptions { specified_module_type: SpecifiedModuleType::EcmaScript, ..ecmascript_options - }, + } + .into(), })], ), ModuleRule::new_all( @@ -290,7 +298,8 @@ impl ModuleOptions { options: EcmascriptOptions { specified_module_type: SpecifiedModuleType::CommonJs, ..ecmascript_options - }, + } + .into(), })], ), ModuleRule::new_all( @@ -302,7 +311,8 @@ impl ModuleOptions { options: EcmascriptOptions { specified_module_type: SpecifiedModuleType::CommonJs, ..ecmascript_options - }, + } + .into(), })], ), ModuleRule::new( @@ -310,7 +320,7 @@ impl ModuleOptions { vec![ModuleRuleEffect::ModuleType( ModuleType::TypescriptDeclaration { transforms: vendor_transforms, - options: ecmascript_options, + options: ecmascript_options_vc, }, )], ), @@ -355,7 +365,7 @@ impl ModuleOptions { ModuleRuleCondition::ResourcePathHasNoExtension, vec![ModuleRuleEffect::ModuleType(ModuleType::Ecmascript { transforms: vendor_transforms, - options: ecmascript_options, + options: ecmascript_options_vc, })], ), ModuleRule::new( @@ -547,7 +557,7 @@ impl ModuleOptions { // This can be overriden by specifying e. g. `as: "*.css"` in the rule. ModuleRuleEffect::ModuleType(ModuleType::Ecmascript { transforms: app_transforms, - options: ecmascript_options, + options: ecmascript_options_vc, }), ModuleRuleEffect::SourceTransforms(Vc::cell(vec![Vc::upcast( WebpackLoaders::new( diff --git a/crates/turbopack/src/module_options/module_rule.rs b/crates/turbopack/src/module_options/module_rule.rs index f1a4dab495af7..99b1431093a6a 100644 --- a/crates/turbopack/src/module_options/module_rule.rs +++ b/crates/turbopack/src/module_options/module_rule.rs @@ -101,7 +101,7 @@ pub enum ModuleType { Ecmascript { transforms: Vc, #[turbo_tasks(trace_ignore)] - options: EcmascriptOptions, + options: Vc, }, Typescript { transforms: Vc, @@ -110,12 +110,12 @@ pub enum ModuleType { // follow references to imported types. analyze_types: bool, #[turbo_tasks(trace_ignore)] - options: EcmascriptOptions, + options: Vc, }, TypescriptDeclaration { transforms: Vc, #[turbo_tasks(trace_ignore)] - options: EcmascriptOptions, + options: Vc, }, Json, Raw, diff --git a/crates/turborepo-analytics/Cargo.toml b/crates/turborepo-analytics/Cargo.toml index c74e17f54fd2f..e774443b9c545 100644 --- a/crates/turborepo-analytics/Cargo.toml +++ b/crates/turborepo-analytics/Cargo.toml @@ -10,7 +10,6 @@ license = "MPL-2.0" workspace = true [dependencies] -async-trait = { workspace = true } futures.workspace = true thiserror = { workspace = true } tokio = { workspace = true, features = ["full", "time"] } diff --git a/crates/turborepo-analytics/src/lib.rs b/crates/turborepo-analytics/src/lib.rs index dd721c70a6060..56486432f8f44 100644 --- a/crates/turborepo-analytics/src/lib.rs +++ b/crates/turborepo-analytics/src/lib.rs @@ -184,7 +184,6 @@ mod tests { time::Duration, }; - use async_trait::async_trait; use tokio::{ select, sync::{mpsc, mpsc::UnboundedReceiver}, @@ -207,7 +206,6 @@ mod tests { } } - #[async_trait] impl AnalyticsClient for DummyClient { async fn record_analytics( &self, diff --git a/crates/turborepo-api-client/Cargo.toml b/crates/turborepo-api-client/Cargo.toml index 4ddd001403dba..2e28f3a877d56 100644 --- a/crates/turborepo-api-client/Cargo.toml +++ b/crates/turborepo-api-client/Cargo.toml @@ -20,7 +20,6 @@ workspace = true [dependencies] anyhow = { workspace = true } -async-trait = { workspace = true } chrono = { workspace = true, features = ["serde"] } lazy_static = { workspace = true } regex = { workspace = true } diff --git a/crates/turborepo-api-client/src/analytics.rs b/crates/turborepo-api-client/src/analytics.rs index 11ffbc1903b47..d073b637c7f3e 100644 --- a/crates/turborepo-api-client/src/analytics.rs +++ b/crates/turborepo-api-client/src/analytics.rs @@ -1,19 +1,18 @@ -use async_trait::async_trait; +use std::future::Future; + use reqwest::Method; pub use turborepo_vercel_api::{AnalyticsEvent, CacheEvent, CacheSource}; use crate::{retry, APIAuth, APIClient, Error}; -#[async_trait] pub trait AnalyticsClient { - async fn record_analytics( + fn record_analytics( &self, api_auth: &APIAuth, events: Vec, - ) -> Result<(), Error>; + ) -> impl Future> + Send; } -#[async_trait] impl AnalyticsClient for APIClient { #[tracing::instrument(skip_all)] async fn record_analytics( diff --git a/crates/turborepo-api-client/src/lib.rs b/crates/turborepo-api-client/src/lib.rs index 6c32430e0b644..72c2fed788e6d 100644 --- a/crates/turborepo-api-client/src/lib.rs +++ b/crates/turborepo-api-client/src/lib.rs @@ -2,9 +2,8 @@ #![feature(error_generic_member_access)] #![deny(clippy::all)] -use std::{backtrace::Backtrace, env}; +use std::{backtrace::Backtrace, env, future::Future, time::Duration}; -use async_trait::async_trait; use lazy_static::lazy_static; use regex::Regex; pub use reqwest::Response; @@ -31,37 +30,47 @@ lazy_static! { Regex::new(r"(?i)(?:^|,) *authorization *(?:,|$)").unwrap(); } -#[async_trait] pub trait Client { - async fn get_user(&self, token: &str) -> Result; - async fn get_teams(&self, token: &str) -> Result; - async fn get_team(&self, token: &str, team_id: &str) -> Result>; + fn get_user(&self, token: &str) -> impl Future> + Send; + fn get_teams(&self, token: &str) -> impl Future> + Send; + fn get_team( + &self, + token: &str, + team_id: &str, + ) -> impl Future>> + Send; fn add_ci_header(request_builder: RequestBuilder) -> RequestBuilder; - async fn get_spaces(&self, token: &str, team_id: Option<&str>) -> Result; - async fn verify_sso_token(&self, token: &str, token_name: &str) -> Result; - async fn handle_403(response: Response) -> Error; + fn get_spaces( + &self, + token: &str, + team_id: Option<&str>, + ) -> impl Future> + Send; + fn verify_sso_token( + &self, + token: &str, + token_name: &str, + ) -> impl Future> + Send; + fn handle_403(response: Response) -> impl Future + Send; fn make_url(&self, endpoint: &str) -> Result; } -#[async_trait] pub trait CacheClient { - async fn get_artifact( + fn get_artifact( &self, hash: &str, token: &str, team_id: Option<&str>, team_slug: Option<&str>, method: Method, - ) -> Result>; - async fn fetch_artifact( + ) -> impl Future>> + Send; + fn fetch_artifact( &self, hash: &str, token: &str, team_id: Option<&str>, team_slug: Option<&str>, - ) -> Result>; + ) -> impl Future>> + Send; #[allow(clippy::too_many_arguments)] - async fn put_artifact( + fn put_artifact( &self, hash: &str, artifact_body: &[u8], @@ -70,31 +79,34 @@ pub trait CacheClient { token: &str, team_id: Option<&str>, team_slug: Option<&str>, - ) -> Result<()>; - async fn artifact_exists( + ) -> impl Future> + Send; + fn artifact_exists( &self, hash: &str, token: &str, team_id: Option<&str>, team_slug: Option<&str>, - ) -> Result>; - async fn get_caching_status( + ) -> impl Future>> + Send; + fn get_caching_status( &self, token: &str, team_id: Option<&str>, team_slug: Option<&str>, - ) -> Result; + ) -> impl Future> + Send; } -#[async_trait] pub trait TokenClient { - async fn get_metadata(&self, token: &str) -> Result; - async fn delete_token(&self, token: &str) -> Result<()>; + fn get_metadata( + &self, + token: &str, + ) -> impl Future> + Send; + fn delete_token(&self, token: &str) -> impl Future> + Send; } #[derive(Clone)] pub struct APIClient { client: reqwest::Client, + cache_client: reqwest::Client, base_url: String, user_agent: String, use_preflight: bool, @@ -113,7 +125,6 @@ pub fn is_linked(api_auth: &Option) -> bool { .map_or(false, |api_auth| api_auth.is_linked()) } -#[async_trait] impl Client for APIClient { async fn get_user(&self, token: &str) -> Result { let url = self.make_url("/v2/user")?; @@ -262,7 +273,6 @@ impl Client for APIClient { } } -#[async_trait] impl CacheClient for APIClient { async fn get_artifact( &self, @@ -362,7 +372,7 @@ impl CacheClient for APIClient { } let mut request_builder = self - .client + .cache_client .put(request_url) .header("Content-Type", "application/octet-stream") .header("x-artifact-duration", duration.to_string()) @@ -414,7 +424,6 @@ impl CacheClient for APIClient { } } -#[async_trait] impl TokenClient for APIClient { async fn get_metadata(&self, token: &str) -> Result { let endpoint = "/v5/user/tokens/current"; @@ -464,9 +473,9 @@ impl TokenClient for APIClient { message: body.error.message, }); } - return Err(Error::ForbiddenToken { + Err(Error::ForbiddenToken { url: self.make_url(endpoint)?.to_string(), - }); + }) } _ => Err(response.error_for_status().unwrap_err().into()), } @@ -516,9 +525,9 @@ impl TokenClient for APIClient { message: body.error.message, }); } - return Err(Error::ForbiddenToken { + Err(Error::ForbiddenToken { url: self.make_url(endpoint)?.to_string(), - }); + }) } _ => Err(response.error_for_status().unwrap_err().into()), } @@ -526,25 +535,50 @@ impl TokenClient for APIClient { } impl APIClient { + /// Create a new APIClient. + /// + /// # Arguments + /// `base_url` - The base URL for the API. + /// `timeout` - The timeout for requests. + /// `upload_timeout` - If specified, uploading files will use `timeout` for + /// the connection, and `upload_timeout` for the total. + /// Otherwise, `timeout` will be used for the total. + /// `version` - The version of the client. + /// `use_preflight` - If true, use the preflight API for all requests. pub fn new( base_url: impl AsRef, - timeout: u64, + timeout: Option, + upload_timeout: Option, version: &str, use_preflight: bool, ) -> Result { - let client_build = if timeout != 0 { - reqwest::Client::builder() - .timeout(std::time::Duration::from_secs(timeout)) - .build() + // for the api client, the timeout applies for the entire duration + // of the request, including the connection phase + let client = reqwest::Client::builder(); + let client = if let Some(dur) = timeout { + client.timeout(dur) } else { - reqwest::Client::builder().build() - }; - - let client = client_build.map_err(Error::TlsError)?; + client + } + .build() + .map_err(Error::TlsError)?; + + // for the cache client, the timeout applies only to the request + // connection time, while the upload timeout applies to the entire + // request + let cache_client = reqwest::Client::builder(); + let cache_client = match (timeout, upload_timeout) { + (Some(dur), Some(upload_dur)) => cache_client.connect_timeout(dur).timeout(upload_dur), + (Some(dur), None) | (None, Some(dur)) => cache_client.timeout(dur), + (None, None) => cache_client, + } + .build() + .map_err(Error::TlsError)?; let user_agent = build_user_agent(version); Ok(APIClient { client, + cache_client, base_url: base_url.as_ref().to_string(), user_agent, use_preflight, @@ -700,7 +734,7 @@ impl AnonAPIClient { pub fn new(base_url: impl AsRef, timeout: u64, version: &str) -> Result { let client_build = if timeout != 0 { reqwest::Client::builder() - .timeout(std::time::Duration::from_secs(timeout)) + .timeout(Duration::from_secs(timeout)) .build() } else { reqwest::Client::builder().build() @@ -729,6 +763,8 @@ fn build_user_agent(version: &str) -> String { #[cfg(test)] mod test { + use std::time::Duration; + use anyhow::Result; use turborepo_vercel_api_mock::start_test_server; use url::Url; @@ -741,7 +777,13 @@ mod test { let handle = tokio::spawn(start_test_server(port)); let base_url = format!("http://localhost:{}", port); - let client = APIClient::new(&base_url, 200, "2.0.0", true)?; + let client = APIClient::new( + &base_url, + Some(Duration::from_secs(200)), + None, + "2.0.0", + true, + )?; let response = client .do_preflight( diff --git a/crates/turborepo-api-client/src/telemetry.rs b/crates/turborepo-api-client/src/telemetry.rs index 8e9a60fb853f8..e3f0466b39d9f 100644 --- a/crates/turborepo-api-client/src/telemetry.rs +++ b/crates/turborepo-api-client/src/telemetry.rs @@ -1,4 +1,5 @@ -use async_trait::async_trait; +use std::future::Future; + use reqwest::Method; use turborepo_vercel_api::telemetry::TelemetryEvent; @@ -6,17 +7,15 @@ use crate::{retry, AnonAPIClient, Error}; const TELEMETRY_ENDPOINT: &str = "/api/turborepo/v1/events"; -#[async_trait] pub trait TelemetryClient { - async fn record_telemetry( + fn record_telemetry( &self, events: Vec, telemetry_id: &str, session_id: &str, - ) -> Result<(), Error>; + ) -> impl Future> + Send; } -#[async_trait] impl TelemetryClient for AnonAPIClient { async fn record_telemetry( &self, diff --git a/crates/turborepo-auth/src/auth/login.rs b/crates/turborepo-auth/src/auth/login.rs index 08ca92baf2bb3..b27cfcb534e12 100644 --- a/crates/turborepo-auth/src/auth/login.rs +++ b/crates/turborepo-auth/src/auth/login.rs @@ -200,7 +200,6 @@ mod tests { } } - #[async_trait] impl Client for MockApiClient { async fn get_user(&self, token: &str) -> turborepo_api_client::Result { if token.is_empty() { @@ -269,7 +268,6 @@ mod tests { } } - #[async_trait] impl TokenClient for MockApiClient { async fn get_metadata( &self, @@ -301,7 +299,6 @@ mod tests { } } - #[async_trait] impl CacheClient for MockApiClient { async fn get_artifact( &self, diff --git a/crates/turborepo-auth/src/auth/logout.rs b/crates/turborepo-auth/src/auth/logout.rs index b5aa77c3e40aa..7b4c4de020194 100644 --- a/crates/turborepo-auth/src/auth/logout.rs +++ b/crates/turborepo-auth/src/auth/logout.rs @@ -82,7 +82,6 @@ impl LogoutOptions { mod tests { use std::backtrace::Backtrace; - use async_trait::async_trait; use reqwest::{RequestBuilder, Response}; use tempfile::tempdir; use turbopath::AbsoluteSystemPathBuf; @@ -100,7 +99,6 @@ mod tests { pub succeed_delete_request: bool, } - #[async_trait] impl Client for MockApiClient { async fn get_user(&self, _token: &str) -> turborepo_api_client::Result { unimplemented!("get_user") @@ -143,7 +141,6 @@ mod tests { } } - #[async_trait] impl TokenClient for MockApiClient { async fn delete_token(&self, _token: &str) -> turborepo_api_client::Result<()> { if self.succeed_delete_request { diff --git a/crates/turborepo-auth/src/auth/sso.rs b/crates/turborepo-auth/src/auth/sso.rs index eeca53e29ab78..7f626fe7fc9e8 100644 --- a/crates/turborepo-auth/src/auth/sso.rs +++ b/crates/turborepo-auth/src/auth/sso.rs @@ -191,7 +191,6 @@ mod tests { } } - #[async_trait] impl Client for MockApiClient { async fn get_user(&self, token: &str) -> turborepo_api_client::Result { if token.is_empty() { @@ -267,7 +266,6 @@ mod tests { } } - #[async_trait] impl TokenClient for MockApiClient { async fn get_metadata( &self, @@ -298,7 +296,6 @@ mod tests { } } - #[async_trait] impl CacheClient for MockApiClient { async fn get_artifact( &self, diff --git a/crates/turborepo-auth/src/lib.rs b/crates/turborepo-auth/src/lib.rs index 74461d8ae0273..6a157e9ae16b4 100644 --- a/crates/turborepo-auth/src/lib.rs +++ b/crates/turborepo-auth/src/lib.rs @@ -266,7 +266,6 @@ fn is_token_active(metadata: &ResponseTokenMetadata, current_time: u128) -> bool mod tests { use std::backtrace::Backtrace; - use async_trait::async_trait; use reqwest::{Method, Response}; use tempfile::tempdir; use turbopath::AbsoluteSystemPathBuf; @@ -396,7 +395,6 @@ mod tests { pub response: MockCachingResponse, } - #[async_trait] impl CacheClient for MockCacheClient { async fn get_artifact( &self, diff --git a/crates/turborepo-cache/src/async_cache.rs b/crates/turborepo-cache/src/async_cache.rs index 658d3892dad6b..94c32a0ad8da6 100644 --- a/crates/turborepo-cache/src/async_cache.rs +++ b/crates/turborepo-cache/src/async_cache.rs @@ -186,7 +186,7 @@ impl AsyncCache { #[cfg(test)] mod tests { - use std::assert_matches::assert_matches; + use std::{assert_matches::assert_matches, time::Duration}; use anyhow::Result; use futures::future::try_join_all; @@ -235,7 +235,13 @@ mod tests { }), }; - let api_client = APIClient::new(format!("http://localhost:{}", port), 200, "2.0.0", true)?; + let api_client = APIClient::new( + format!("http://localhost:{}", port), + Some(Duration::from_secs(200)), + None, + "2.0.0", + true, + )?; let api_auth = Some(APIAuth { team_id: Some("my-team-id".to_string()), token: "my-token".to_string(), @@ -317,7 +323,13 @@ mod tests { // Initialize client with invalid API url to ensure that we don't hit the // network - let api_client = APIClient::new("http://example.com", 200, "2.0.0", true)?; + let api_client = APIClient::new( + "http://example.com", + Some(Duration::from_secs(200)), + None, + "2.0.0", + true, + )?; let api_auth = Some(APIAuth { team_id: Some("my-team-id".to_string()), token: "my-token".to_string(), @@ -405,7 +417,13 @@ mod tests { }), }; - let api_client = APIClient::new(format!("http://localhost:{}", port), 200, "2.0.0", true)?; + let api_client = APIClient::new( + format!("http://localhost:{}", port), + Some(Duration::from_secs(200)), + None, + "2.0.0", + true, + )?; let api_auth = Some(APIAuth { team_id: Some("my-team-id".to_string()), token: "my-token".to_string(), diff --git a/crates/turborepo-cache/src/fs.rs b/crates/turborepo-cache/src/fs.rs index 6716ec86ebe50..629d337241451 100644 --- a/crates/turborepo-cache/src/fs.rs +++ b/crates/turborepo-cache/src/fs.rs @@ -182,6 +182,8 @@ impl FSCache { #[cfg(test)] mod test { + use std::time::Duration; + use anyhow::Result; use futures::future::try_join_all; use tempfile::tempdir; @@ -216,7 +218,13 @@ mod test { let repo_root_path = AbsoluteSystemPath::from_std_path(repo_root.path())?; test_case.initialize(repo_root_path)?; - let api_client = APIClient::new(format!("http://localhost:{}", port), 200, "2.0.0", true)?; + let api_client = APIClient::new( + format!("http://localhost:{}", port), + Some(Duration::from_secs(200)), + None, + "2.0.0", + true, + )?; let api_auth = APIAuth { team_id: Some("my-team".to_string()), token: "my-token".to_string(), diff --git a/crates/turborepo-cache/src/http.rs b/crates/turborepo-cache/src/http.rs index fdb02afe6b471..510fa1e8ee795 100644 --- a/crates/turborepo-cache/src/http.rs +++ b/crates/turborepo-cache/src/http.rs @@ -75,7 +75,10 @@ impl HTTPCache { .map(|signer| signer.generate_tag(hash.as_bytes(), &artifact_body)) .transpose()?; - self.client + tracing::debug!("uploading {}", hash); + + match self + .client .put_artifact( hash, &artifact_body, @@ -85,9 +88,20 @@ impl HTTPCache { self.api_auth.team_id.as_deref(), self.api_auth.team_slug.as_deref(), ) - .await?; - - Ok(()) + .await + { + Ok(_) => { + tracing::debug!("uploaded {}", hash); + Ok(()) + } + Err(turborepo_api_client::Error::ReqwestError(e)) if e.is_timeout() => { + Err(CacheError::TimeoutError(hash.to_string())) + } + Err(turborepo_api_client::Error::ReqwestError(e)) if e.is_connect() => { + Err(CacheError::ConnectError) + } + Err(e) => Err(e.into()), + } } #[tracing::instrument(skip_all)] @@ -235,6 +249,8 @@ impl HTTPCache { #[cfg(test)] mod test { + use std::time::Duration; + use anyhow::Result; use futures::future::try_join_all; use tempfile::tempdir; @@ -276,7 +292,13 @@ mod test { let files = &test_case.files; let duration = test_case.duration; - let api_client = APIClient::new(format!("http://localhost:{}", port), 200, "2.0.0", true)?; + let api_client = APIClient::new( + format!("http://localhost:{}", port), + Some(Duration::from_secs(200)), + None, + "2.0.0", + true, + )?; let opts = CacheOpts::default(); let api_auth = APIAuth { team_id: Some("my-team".to_string()), diff --git a/crates/turborepo-cache/src/lib.rs b/crates/turborepo-cache/src/lib.rs index 36423adda1dc8..0f9fbd00de00d 100644 --- a/crates/turborepo-cache/src/lib.rs +++ b/crates/turborepo-cache/src/lib.rs @@ -44,6 +44,10 @@ pub enum CacheError { InvalidFilePath(String, #[backtrace] Backtrace), #[error("failed to contact remote cache: {0}")] ApiClientError(Box, #[backtrace] Backtrace), + #[error("the cache artifact for {0} was too large to upload within the timeout")] + TimeoutError(String), + #[error("could not connect to the cache")] + ConnectError, #[error("signing artifact failed: {0}")] SignatureError(#[from] SignatureError, #[backtrace] Backtrace), #[error("invalid duration")] diff --git a/crates/turborepo-filewatch/Cargo.toml b/crates/turborepo-filewatch/Cargo.toml index 594fb37f1914c..3b8285a80c9db 100644 --- a/crates/turborepo-filewatch/Cargo.toml +++ b/crates/turborepo-filewatch/Cargo.toml @@ -14,7 +14,7 @@ futures = { version = "0.3.26" } itertools = { workspace = true } nibble_vec = "0.1.0" notify = { workspace = true } -radix_trie = "0.2.1" +radix_trie = { workspace = true } thiserror = "1.0.38" tokio = { workspace = true, features = ["full", "time"] } tracing = "0.1.37" diff --git a/crates/turborepo-filewatch/src/debouncer.rs b/crates/turborepo-filewatch/src/debouncer.rs new file mode 100644 index 0000000000000..0f169b2d715b6 --- /dev/null +++ b/crates/turborepo-filewatch/src/debouncer.rs @@ -0,0 +1,127 @@ +use std::{fmt::Debug, sync::Mutex, time::Duration}; + +use tokio::{select, sync, time::Instant}; +use tracing::trace; + +pub(crate) struct Debouncer { + bump: sync::Notify, + serial: Mutex>, + timeout: Duration, +} + +const DEFAULT_DEBOUNCE_TIMEOUT: Duration = Duration::from_millis(10); + +impl Default for Debouncer { + fn default() -> Self { + Self::new(DEFAULT_DEBOUNCE_TIMEOUT) + } +} + +impl Debug for Debouncer { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let serial = { self.serial.lock().expect("lock is valid") }; + f.debug_struct("Debouncer") + .field("is_pending", &serial.is_some()) + .field("timeout", &self.timeout) + .finish() + } +} + +impl Debouncer { + pub(crate) fn new(timeout: Duration) -> Self { + let bump = sync::Notify::new(); + let serial = Mutex::new(Some(0)); + Self { + bump, + serial, + timeout, + } + } + + pub(crate) fn bump(&self) -> bool { + let mut serial = self.serial.lock().expect("lock is valid"); + match *serial { + None => false, + Some(previous) => { + *serial = Some(previous + 1); + self.bump.notify_one(); + true + } + } + } + + pub(crate) async fn debounce(&self) { + let mut serial = { + self.serial + .lock() + .expect("lock is valid") + .expect("only this thread sets the value to None") + }; + let mut deadline = Instant::now() + self.timeout; + loop { + let timeout = tokio::time::sleep_until(deadline); + select! { + _ = self.bump.notified() => { + trace!("debouncer notified"); + // reset timeout + let current_serial = self.serial.lock().expect("lock is valid").expect("only this thread sets the value to None"); + if current_serial == serial { + // we timed out between the serial update and the notification. + // ignore this notification, we've already bumped the timer + continue; + } else { + serial = current_serial; + deadline = Instant::now() + self.timeout; + } + } + _ = timeout => { + // check if serial is still valid. It's possible a bump came in before the timeout, + // but we haven't been notified yet. + let mut current_serial_opt = self.serial.lock().expect("lock is valid"); + let current_serial = current_serial_opt.expect("only this thread sets the value to None"); + if current_serial == serial { + // if the serial is what we last observed, and the timer expired, we timed out. + // we're done. Mark that we won't accept any more bumps and return + *current_serial_opt = None; + return; + } else { + serial = current_serial; + deadline = Instant::now() + self.timeout; + } + } + } + } + } +} + +#[cfg(test)] +mod tests { + use std::{ + sync::Arc, + time::{Duration, Instant}, + }; + + use crate::debouncer::Debouncer; + + #[tokio::test] + async fn test_debouncer() { + let debouncer = Arc::new(Debouncer::new(Duration::from_millis(10))); + let debouncer_copy = debouncer.clone(); + let handle = tokio::task::spawn(async move { + debouncer_copy.debounce().await; + }); + for _ in 0..10 { + // assert that we can continue bumping it past the original timeout + tokio::time::sleep(Duration::from_millis(2)).await; + assert!(debouncer.bump()); + } + let start = Instant::now(); + handle.await.unwrap(); + let end = Instant::now(); + // give some wiggle room to account for race conditions, but assert that we + // didn't immediately complete after the last bump + assert!(end - start > Duration::from_millis(5)); + // we shouldn't be able to bump it after it's run out it's timeout + assert!(!debouncer.bump()); + } +} diff --git a/crates/turborepo-filewatch/src/globwatcher.rs b/crates/turborepo-filewatch/src/globwatcher.rs index 7da6f6d29981c..6fd6bc563d360 100644 --- a/crates/turborepo-filewatch/src/globwatcher.rs +++ b/crates/turborepo-filewatch/src/globwatcher.rs @@ -24,15 +24,20 @@ type Hash = String; pub struct GlobSet { include: HashMap>, exclude: Any<'static>, + // Note that these globs do not include the leading '!' character exclude_raw: BTreeSet, } impl GlobSet { pub fn as_inputs(&self) -> Vec { let mut inputs: Vec = self.include.keys().cloned().collect(); - inputs.extend(self.exclude_raw.iter().cloned()); + inputs.extend(self.exclude_raw.iter().map(|s| format!("!{}", s))); inputs } + + pub fn matches(&self, input: &RelativeUnixPath) -> bool { + self.include.values().any(|glob| glob.is_match(input)) && !self.exclude.is_match(input) + } } impl std::fmt::Debug for GlobSet { @@ -133,6 +138,16 @@ impl GlobSet { }; Self::from_raw(includes, excludes) } + + pub fn is_package_local(&self) -> bool { + self.include + .keys() + .all(|raw_glob| !raw_glob.starts_with("../")) + && self + .exclude_raw + .iter() + .all(|raw_glob| !raw_glob.starts_with("../")) + } } #[derive(Debug, Error)] diff --git a/crates/turborepo-filewatch/src/hash_watcher.rs b/crates/turborepo-filewatch/src/hash_watcher.rs index d154d1f0e28db..7578cdf0b28b6 100644 --- a/crates/turborepo-filewatch/src/hash_watcher.rs +++ b/crates/turborepo-filewatch/src/hash_watcher.rs @@ -2,7 +2,7 @@ use std::{ collections::{HashMap, HashSet}, sync::{ atomic::{AtomicUsize, Ordering}, - Arc, Mutex, + Arc, }, time::Duration, }; @@ -12,15 +12,22 @@ use radix_trie::{Trie, TrieCommon}; use thiserror::Error; use tokio::{ select, - sync::{self, broadcast, mpsc, oneshot, watch}, - time::Instant, + sync::{broadcast, mpsc, oneshot, watch}, }; use tracing::{debug, trace}; -use turbopath::{AbsoluteSystemPathBuf, AnchoredSystemPath, AnchoredSystemPathBuf, PathRelation}; +use turbopath::{AbsoluteSystemPathBuf, AnchoredSystemPath, AnchoredSystemPathBuf}; use turborepo_repository::discovery::DiscoveryResponse; -use turborepo_scm::{package_deps::GitHashes, Error as SCMError, SCM}; +use turborepo_scm::{ + package_deps::{GitHashes, INPUT_INCLUDE_DEFAULT_FILES}, + Error as SCMError, SCM, +}; -use crate::{globwatcher::GlobSet, package_watcher::DiscoveryData, NotifyError, OptionalWatch}; +use crate::{ + debouncer::Debouncer, + globwatcher::{GlobError, GlobSet}, + package_watcher::DiscoveryData, + NotifyError, OptionalWatch, +}; pub struct HashWatcher { _exit_tx: oneshot::Sender<()>, @@ -28,10 +35,57 @@ pub struct HashWatcher { query_tx: mpsc::Sender, } +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum InputGlobs { + Default, + DefaultWithExtras(GlobSet), + Specific(GlobSet), +} + +impl InputGlobs { + pub fn from_raw(mut raw: Vec) -> Result { + if raw.is_empty() { + Ok(Self::Default) + } else if let Some(default_pos) = raw.iter().position(|g| g == INPUT_INCLUDE_DEFAULT_FILES) + { + raw.remove(default_pos); + Ok(Self::DefaultWithExtras(GlobSet::from_raw_unfiltered(raw)?)) + } else { + Ok(Self::Specific(GlobSet::from_raw_unfiltered(raw)?)) + } + } + + fn is_package_local(&self) -> bool { + match self { + InputGlobs::Default => true, + InputGlobs::DefaultWithExtras(glob_set) => glob_set.is_package_local(), + InputGlobs::Specific(glob_set) => glob_set.is_package_local(), + } + } + + fn as_inputs(&self) -> Vec { + match self { + InputGlobs::Default => Vec::new(), + InputGlobs::DefaultWithExtras(glob_set) => { + let mut inputs = glob_set.as_inputs(); + inputs.push(INPUT_INCLUDE_DEFAULT_FILES.to_string()); + inputs + } + InputGlobs::Specific(glob_set) => glob_set.as_inputs(), + } + } +} + #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub struct HashSpec { pub package_path: AnchoredSystemPathBuf, - pub inputs: Option, + pub inputs: InputGlobs, +} + +impl HashSpec { + fn is_package_local(&self) -> bool { + self.inputs.is_package_local() + } } #[derive(Error, Debug)] @@ -42,6 +96,8 @@ pub enum Error { Unavailable(String), #[error("package not found: {} {:?}", .0.package_path, .0.inputs)] UnknownPackage(HashSpec), + #[error("unsupported: glob traverses out of the package")] + UnsupportedGlob, } // Communication errors that all funnel to Unavailable @@ -103,6 +159,7 @@ struct Subscriber { next_version: AtomicUsize, } +#[derive(Debug)] enum Query { GetHash(HashSpec, oneshot::Sender>), } @@ -113,92 +170,11 @@ enum Query { #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] struct Version(usize); -struct HashDebouncer { - bump: sync::Notify, - serial: Mutex>, - timeout: Duration, -} - -const DEFAULT_DEBOUNCE_TIMEOUT: Duration = Duration::from_millis(10); - -impl Default for HashDebouncer { - fn default() -> Self { - Self::new(DEFAULT_DEBOUNCE_TIMEOUT) - } -} - -impl HashDebouncer { - fn new(timeout: Duration) -> Self { - let bump = sync::Notify::new(); - let serial = Mutex::new(Some(0)); - Self { - bump, - serial, - timeout, - } - } - - fn bump(&self) -> bool { - let mut serial = self.serial.lock().expect("lock is valid"); - match *serial { - None => false, - Some(previous) => { - *serial = Some(previous + 1); - self.bump.notify_one(); - true - } - } - } - - async fn debounce(&self) { - let mut serial = { - self.serial - .lock() - .expect("lock is valid") - .expect("only this thread sets the value to None") - }; - let mut deadline = Instant::now() + self.timeout; - loop { - let timeout = tokio::time::sleep_until(deadline); - select! { - _ = self.bump.notified() => { - debug!("debouncer notified"); - // reset timeout - let current_serial = self.serial.lock().expect("lock is valid").expect("only this thread sets the value to None"); - if current_serial == serial { - // we timed out between the serial update and the notification. - // ignore this notification, we've already bumped the timer - continue; - } else { - serial = current_serial; - deadline = Instant::now() + self.timeout; - } - } - _ = timeout => { - // check if serial is still valid. It's possible a bump came in before the timeout, - // but we haven't been notified yet. - let mut current_serial_opt = self.serial.lock().expect("lock is valid"); - let current_serial = current_serial_opt.expect("only this thread sets the value to None"); - if current_serial == serial { - // if the serial is what we last observed, and the timer expired, we timed out. - // we're done. Mark that we won't accept any more bumps and return - *current_serial_opt = None; - return; - } else { - serial = current_serial; - deadline = Instant::now() + self.timeout; - } - } - } - } - } -} - enum HashState { Hashes(GitHashes), Pending( Version, - Arc, + Arc, Vec>>, ), Unavailable(String), @@ -214,7 +190,7 @@ enum HashState { // We *could* implement TrieKey in AnchoredSystemPathBuf and avoid the String // conversion, if we decide we want to add the radix_trie dependency to // turbopath. -struct FileHashes(Trie, HashState>>); +struct FileHashes(Trie>); impl FileHashes { fn new() -> Self { @@ -253,21 +229,56 @@ impl FileHashes { } } - fn get_package_path(&self, file_path: &AnchoredSystemPath) -> Option<&AnchoredSystemPath> { + fn get_changed_specs(&self, file_path: &AnchoredSystemPath) -> HashSet { self.0 .get_ancestor(file_path.as_str()) - .and_then(|subtrie| subtrie.key()) - .map(|package_path| { - AnchoredSystemPath::new(package_path).expect("keys are valid AnchoredSystemPaths") - }) - .filter(|package_path| { + // verify we have a key + .and_then(|subtrie| subtrie.key().map(|key| (key, subtrie))) + // convert key to AnchoredSystemPath, and verify we have a value + .and_then(|(package_path, subtrie)| { + let package_path = AnchoredSystemPath::new(package_path) + .expect("keys are valid AnchoredSystemPaths"); // handle scenarios where even though we've found an ancestor, it might be a // sibling file or directory that starts with the same prefix, // e,g an update to apps/foo_decoy when the package path is - // apps/foo. Note that relation_to_path will return Parent for - // equivalent paths. - package_path.relation_to_path(file_path) == PathRelation::Parent + // apps/foo. + if let Some(package_path_to_file) = file_path.strip_prefix(package_path) { + // Pass along the path to the package, the path _within_ the package to this + // change, in unix format, and the set of input specs that + // we're tracking. + subtrie + .value() + .map(|specs| (package_path, package_path_to_file.to_unix(), specs)) + } else { + None + } }) + // now that we have a path and a set of specs, filter the specs to the relevant ones + .map(|(package_path, change_in_package, input_globs)| { + input_globs + .keys() + .filter_map(|input_globs| match input_globs { + InputGlobs::Default => Some(HashSpec { + package_path: package_path.to_owned(), + inputs: InputGlobs::Default, + }), + inputs @ InputGlobs::DefaultWithExtras(_) => Some(HashSpec { + package_path: package_path.to_owned(), + inputs: inputs.clone(), + }), + inputs @ InputGlobs::Specific(glob_set) + if glob_set.matches(&change_in_package) => + { + Some(HashSpec { + package_path: package_path.to_owned(), + inputs: inputs.clone(), + }) + } + _ => None, + }) + .collect::>() + }) + .unwrap_or_default() } fn drain(&mut self, reason: &str) { @@ -393,7 +404,7 @@ impl Subscriber { } }, Some(query) = self.query_rx.recv() => { - self.handle_query(query, &mut hashes); + self.handle_query(query, &mut hashes, &hash_update_tx); } } } @@ -415,9 +426,24 @@ impl Subscriber { // We currently only support a single query, getting hashes for a given // HashSpec. - fn handle_query(&self, query: Query, hashes: &mut FileHashes) { + fn handle_query( + &self, + query: Query, + hashes: &mut FileHashes, + hash_update_tx: &mpsc::Sender, + ) { + //trace!("handling query {query:?}"); match query { Query::GetHash(spec, tx) => { + // We don't currently support inputs that are not package-local. Adding this + // support would require tracking arbitrary file paths and + // mapping them back to packages. It is doable if we want to + // attempt it in the future. + if !spec.is_package_local() { + let _ = tx.send(Err(Error::UnsupportedGlob)); + trace!("unsupported glob in query {:?}", spec); + return; + } if let Some(state) = hashes.get_mut(&spec) { match state { HashState::Hashes(hashes) => { @@ -430,7 +456,20 @@ impl Subscriber { let _ = tx.send(Err(Error::HashingError(e.clone()))); } } + } else if !matches!(spec.inputs, InputGlobs::Default) + && hashes.contains_key(&HashSpec { + package_path: spec.package_path.clone(), + inputs: InputGlobs::Default, + }) + { + // in this scenario, we know the package exists, but we aren't tracking these + // particular inputs. Queue a hash request for them. + let (version, debouncer) = self.queue_package_hash(&spec, hash_update_tx, true); + // this request will likely time out. However, if the client has asked for + // this spec once, they might ask again, and we can start tracking it. + hashes.insert(spec, HashState::Pending(version, debouncer, vec![tx])); } else { + // We don't know anything about this package. let _ = tx.send(Err(Error::UnknownPackage(spec))); } } @@ -453,7 +492,6 @@ impl Subscriber { if *existing_version == version { match result { Ok(hashes) => { - debug!("updating hash at {:?}", spec.package_path); for pending_query in pending_queries.drain(..) { // We don't care if the client has gone away let _ = pending_query.send(Ok(hashes.clone())); @@ -478,26 +516,29 @@ impl Subscriber { &self, spec: &HashSpec, hash_update_tx: &mpsc::Sender, - ) -> (Version, Arc) { + immediate: bool, + ) -> (Version, Arc) { let version = Version(self.next_version.fetch_add(1, Ordering::SeqCst)); let tx = hash_update_tx.clone(); let spec = spec.clone(); let repo_root = self.repo_root.clone(); let scm = self.scm.clone(); - let debouncer = Arc::new(HashDebouncer::default()); + let debouncer = if immediate { + Debouncer::new(Duration::from_millis(0)) + } else { + Debouncer::default() + }; + let debouncer = Arc::new(debouncer); let debouncer_copy = debouncer.clone(); tokio::task::spawn(async move { debouncer_copy.debounce().await; // Package hashing involves blocking IO calls, so run on a blocking thread. tokio::task::spawn_blocking(move || { let telemetry = None; - let inputs = spec.inputs.as_ref().map(|globs| globs.as_inputs()); - let result = scm.get_package_file_hashes( - &repo_root, - &spec.package_path, - inputs.as_deref().unwrap_or_default(), - telemetry, - ); + let inputs = spec.inputs.as_inputs(); + let result = + scm.get_package_file_hashes(&repo_root, &spec.package_path, &inputs, telemetry); + trace!("hashing complete for {:?}", spec); let _ = tx.blocking_send(HashUpdate { spec, version, @@ -514,7 +555,7 @@ impl Subscriber { hashes: &mut FileHashes, hash_update_tx: &mpsc::Sender, ) { - let mut changed_packages: HashSet = HashSet::new(); + let mut changed_specs: HashSet = HashSet::new(); for path in event.paths { let path = AbsoluteSystemPathBuf::try_from(path).expect("event path is a valid path"); let repo_relative_change_path = self @@ -523,30 +564,33 @@ impl Subscriber { .expect("event path is in the repository"); // If this change is not relevant to a package, ignore it trace!("file change at {:?}", repo_relative_change_path); - if let Some(package_path) = hashes.get_package_path(&repo_relative_change_path) { + let changed_specs_for_path = hashes.get_changed_specs(&repo_relative_change_path); + if !changed_specs_for_path.is_empty() { // We have a file change in a package, and we haven't seen this package yet. // Queue it for rehashing. // TODO: further qualification. Which sets of inputs? Is this file .gitignored? // We are somewhat saved here by deferring to the SCM to do the hashing. A // change to a gitignored file will trigger a re-hash, but won't // actually affect what the hash is. - trace!("package changed: {:?}", package_path); - changed_packages.insert(package_path.to_owned()); + trace!("specs changed: {:?}", changed_specs_for_path); + //changed_specs.insert(package_path.to_owned()); + changed_specs.extend(changed_specs_for_path.into_iter()); } else { trace!("Ignoring change to {repo_relative_change_path}"); } } // TODO: handle different sets of inputs - for package_path in changed_packages { - let spec = HashSpec { - package_path, - inputs: None, - }; + + // Any rehashing we do was triggered by a file event, so don't do it + // immediately. Wait for the debouncer to time out instead. + let immediate = false; + for spec in changed_specs { match hashes.get_mut(&spec) { // Technically this shouldn't happen, the package_paths are sourced from keys in // hashes. None => { - let (version, debouncer) = self.queue_package_hash(&spec, hash_update_tx); + let (version, debouncer) = + self.queue_package_hash(&spec, hash_update_tx, immediate); hashes.insert(spec, HashState::Pending(version, debouncer, vec![])); } Some(entry) => { @@ -556,7 +600,7 @@ impl Subscriber { // progress. Drop this calculation and start // a new one let (version, debouncer) = - self.queue_package_hash(&spec, hash_update_tx); + self.queue_package_hash(&spec, hash_update_tx, immediate); let mut swap_target = vec![]; std::mem::swap(txs, &mut swap_target); *entry = HashState::Pending(version, debouncer, swap_target); @@ -564,7 +608,8 @@ impl Subscriber { } else { // it's not a pending hash calculation, overwrite the entry with a new // pending calculation - let (version, debouncer) = self.queue_package_hash(&spec, hash_update_tx); + let (version, debouncer) = + self.queue_package_hash(&spec, hash_update_tx, immediate); *entry = HashState::Pending(version, debouncer, vec![]); } } @@ -597,13 +642,17 @@ impl Subscriber { |package_path| !package_paths.contains(package_path), "package was removed", ); + // package data updates are triggered by file events, so don't immediately + // start rehashing, use the debouncer to wait for a quiet period. + let immediate = false; for package_path in package_paths { let spec = HashSpec { package_path, - inputs: None, + inputs: InputGlobs::Default, }; if !hashes.contains_key(&spec) { - let (version, debouncer) = self.queue_package_hash(&spec, hash_update_tx); + let (version, debouncer) = + self.queue_package_hash(&spec, hash_update_tx, immediate); hashes.insert(spec, HashState::Pending(version, debouncer, vec![])); } } @@ -621,8 +670,6 @@ impl Subscriber { mod tests { use std::{ assert_matches::assert_matches, - ops::Deref, - sync::Arc, time::{Duration, Instant}, }; @@ -636,7 +683,8 @@ mod tests { use super::{FileHashes, HashState}; use crate::{ cookies::CookieWriter, - hash_watcher::{HashDebouncer, HashSpec, HashWatcher}, + globwatcher::GlobSet, + hash_watcher::{HashSpec, HashWatcher, InputGlobs}, package_watcher::PackageWatcher, FileSystemWatcher, }; @@ -784,7 +832,7 @@ mod tests { &hash_watcher, HashSpec { package_path: repo_root.anchor(&foo_path).unwrap(), - inputs: None, + inputs: InputGlobs::Default, }, Duration::from_secs(2), make_expected(vec![ @@ -804,7 +852,7 @@ mod tests { &hash_watcher, HashSpec { package_path: repo_root.anchor(&foo_path).unwrap(), - inputs: None, + inputs: InputGlobs::Default, }, Duration::from_secs(2), make_expected(vec![ @@ -832,7 +880,7 @@ mod tests { &hash_watcher, HashSpec { package_path: repo_root.anchor(&foo_path).unwrap(), - inputs: None, + inputs: InputGlobs::Default, }, Duration::from_secs(2), make_expected(vec![ @@ -866,15 +914,16 @@ mod tests { HashWatcher::new(repo_root.clone(), package_discovery, watcher.watch(), scm); let bar_path = repo_root.join_components(&["packages", "bar"]); + let bar_spec = HashSpec { + package_path: repo_root.anchor(&bar_path).unwrap(), + inputs: InputGlobs::Default, + }; // We need to give filewatching time to do the initial scan, // but this should resolve in short order to the expected value. retry_get_hash( &hash_watcher, - HashSpec { - package_path: repo_root.anchor(&bar_path).unwrap(), - inputs: None, - }, + bar_spec.clone(), Duration::from_secs(2), make_expected(vec![ ("bar-file", "b9bdb1e4875f7397b3f68c104bc249de0ecd3f8e"), @@ -887,10 +936,7 @@ mod tests { retry_get_hash( &hash_watcher, - HashSpec { - package_path: repo_root.anchor(&bar_path).unwrap(), - inputs: None, - }, + bar_spec, Duration::from_secs(2), make_expected(vec![ ("baz-file", "a5395ccf1b8966f3ea805aff0851eac13acb3540"), @@ -921,12 +967,32 @@ mod tests { let hash_watcher = HashWatcher::new(repo_root.clone(), package_discovery, watcher.watch(), scm); + // Ensure everything is up and running so we can verify the correct error for a + // non-existing package + let foo_path = repo_root.join_components(&["packages", "foo"]); + // We need to give filewatching time to do the initial scan, + // but this should resolve in short order to the expected value. + retry_get_hash( + &hash_watcher, + HashSpec { + package_path: repo_root.anchor(&foo_path).unwrap(), + inputs: InputGlobs::Default, + }, + Duration::from_secs(2), + make_expected(vec![ + ("foo-file", "9317666a2e7b729b740c706ab79724952c97bde4"), + ("package.json", "395351bdd7167f351af3396d3225ebe97a7a4d13"), + (".gitignore", "89f9ac04aac6c8ee66e158853e7d0439b3ec782d"), + ]), + ) + .await; + let non_existent_path = repo_root.join_components(&["packages", "non-existent"]); let relative_non_existent_path = repo_root.anchor(&non_existent_path).unwrap(); let result = hash_watcher .get_file_hashes(HashSpec { package_path: relative_non_existent_path.clone(), - inputs: None, + inputs: InputGlobs::Default, }) .await; assert_matches!(result, Err(crate::hash_watcher::Error::UnknownPackage(unknown_spec)) if unknown_spec.package_path == relative_non_existent_path); @@ -957,6 +1023,7 @@ mod tests { error = Some(e); } } + tokio::time::sleep(Duration::from_millis(200)).await; } panic!( "failed to get expected hashes. Error {:?}, last hashes: {:?}", @@ -980,55 +1047,318 @@ mod tests { let foo_path = root.join_components(&["apps", "foo"]); let foo_spec = HashSpec { package_path: foo_path.clone(), - inputs: None, + inputs: InputGlobs::Default, }; hashes.insert(foo_spec, HashState::Hashes(GitHashes::new())); let foo_bar_path = root.join_components(&["apps", "foobar"]); let foo_bar_spec = HashSpec { package_path: foo_bar_path.clone(), - inputs: None, + inputs: InputGlobs::Default, }; hashes.insert(foo_bar_spec, HashState::Hashes(GitHashes::new())); let foo_candidate = foo_path.join_component("README.txt"); - let result = hashes.get_package_path(&foo_candidate).unwrap(); - assert_eq!(result, foo_path.deref()); + let result = hashes.get_changed_specs(&foo_candidate); + assert_eq!(result.len(), 1); + assert_eq!(result.into_iter().next().unwrap().package_path, foo_path); let foo_bar_candidate = foo_bar_path.join_component("README.txt"); - let result = hashes.get_package_path(&foo_bar_candidate).unwrap(); - assert_eq!(result, foo_bar_path.deref()); + let result = hashes.get_changed_specs(&foo_bar_candidate); + assert_eq!( + result.into_iter().next().unwrap().package_path, + foo_bar_path + ); // try a path that is a *sibling* of a package, but not itself a package let sibling = root.join_components(&["apps", "sibling"]); - let result = hashes.get_package_path(&sibling); - assert!(result.is_none()); + let result = hashes.get_changed_specs(&sibling); + assert!(result.is_empty()); // try a path that is a *sibling* of a package, but not itself a package, but // starts with the prefix of a package let decoy = root.join_components(&["apps", "foodecoy"]); - let result = hashes.get_package_path(&decoy); - assert!(result.is_none()); + let result = hashes.get_changed_specs(&decoy); + assert!(result.is_empty()); } #[tokio::test] - async fn test_debouncer() { - let debouncer = Arc::new(HashDebouncer::new(Duration::from_millis(10))); - let debouncer_copy = debouncer.clone(); - let handle = tokio::task::spawn(async move { - debouncer_copy.debounce().await; - }); - for _ in 0..10 { - // assert that we can continue bumping it past the original timeout - tokio::time::sleep(Duration::from_millis(2)).await; - assert!(debouncer.bump()); - } - let start = Instant::now(); - handle.await.unwrap(); - let end = Instant::now(); - // give some wiggle room to account for race conditions, but assert that we - // didn't immediately complete after the last bump - assert!(end - start > Duration::from_millis(5)); - // we shouldn't be able to bump it after it's run out it's timeout - assert!(!debouncer.bump()); + #[tracing_test::traced_test] + async fn test_basic_file_changes_with_inputs() { + let (_tmp, _repo, repo_root) = setup_fixture(); + + let watcher = FileSystemWatcher::new_with_default_cookie_dir(&repo_root).unwrap(); + + let recv = watcher.watch(); + let cookie_writer = CookieWriter::new( + watcher.cookie_dir(), + Duration::from_millis(100), + recv.clone(), + ); + + let scm = SCM::new(&repo_root); + assert!(!scm.is_manual()); + let package_watcher = PackageWatcher::new(repo_root.clone(), recv, cookie_writer).unwrap(); + let package_discovery = package_watcher.watch_discovery(); + let hash_watcher = + HashWatcher::new(repo_root.clone(), package_discovery, watcher.watch(), scm); + + let foo_path = repo_root.join_components(&["packages", "foo"]); + let foo_inputs = GlobSet::from_raw(vec!["*-file".to_string()], vec![]).unwrap(); + let foo_spec = HashSpec { + package_path: repo_root.anchor(&foo_path).unwrap(), + inputs: InputGlobs::Specific(foo_inputs), + }; + // package.json is always included, whether it matches your inputs or not. + retry_get_hash( + &hash_watcher, + foo_spec.clone(), + Duration::from_secs(2), + make_expected(vec![ + // Note that without inputs, we'd also get the .gitignore file + ("foo-file", "9317666a2e7b729b740c706ab79724952c97bde4"), + ("package.json", "395351bdd7167f351af3396d3225ebe97a7a4d13"), + ]), + ) + .await; + + // update foo-file + let foo_file_path = repo_root.join_components(&["packages", "foo", "foo-file"]); + foo_file_path + .create_with_contents("new foo-file contents") + .unwrap(); + retry_get_hash( + &hash_watcher, + foo_spec.clone(), + Duration::from_secs(2), + make_expected(vec![ + ("foo-file", "5f6796bbd23dcdc9d30d07a2d8a4817c34b7f1e7"), + ("package.json", "395351bdd7167f351af3396d3225ebe97a7a4d13"), + ]), + ) + .await; + } + + #[tokio::test] + #[tracing_test::traced_test] + async fn test_switch_branch_with_inputs() { + let (_tmp, repo, repo_root) = setup_fixture(); + + let watcher = FileSystemWatcher::new_with_default_cookie_dir(&repo_root).unwrap(); + + let recv = watcher.watch(); + let cookie_writer = CookieWriter::new( + watcher.cookie_dir(), + Duration::from_millis(100), + recv.clone(), + ); + + let scm = SCM::new(&repo_root); + assert!(!scm.is_manual()); + let package_watcher = PackageWatcher::new(repo_root.clone(), recv, cookie_writer).unwrap(); + let package_discovery = package_watcher.watch_discovery(); + let hash_watcher = + HashWatcher::new(repo_root.clone(), package_discovery, watcher.watch(), scm); + + let bar_path = repo_root.join_components(&["packages", "bar"]); + + let bar_inputs = GlobSet::from_raw(vec!["*z-file".to_string()], vec![]).unwrap(); + let bar_spec = HashSpec { + package_path: repo_root.anchor(&bar_path).unwrap(), + inputs: InputGlobs::Specific(bar_inputs), + }; + + // package.json is always included, whether it matches your inputs or not. + retry_get_hash( + &hash_watcher, + bar_spec.clone(), + Duration::from_secs(2), + make_expected(vec![( + "package.json", + "b39117e03f0dbe217b957f58a2ad78b993055088", + )]), + ) + .await; + + create_fixture_branch(&repo, &repo_root); + + retry_get_hash( + &hash_watcher, + bar_spec, + Duration::from_secs(2), + make_expected(vec![ + ("baz-file", "a5395ccf1b8966f3ea805aff0851eac13acb3540"), + ("package.json", "b39117e03f0dbe217b957f58a2ad78b993055088"), + ]), + ) + .await; + } + + #[tokio::test] + #[tracing_test::traced_test] + async fn test_inputs_with_turbo_defaults() { + let (_tmp, _repo, repo_root) = setup_fixture(); + // Add an ignored file + let foo_path = repo_root.join_components(&["packages", "foo"]); + let ignored_file_path = foo_path.join_components(&["out", "ignored-file"]); + ignored_file_path.ensure_dir().unwrap(); + ignored_file_path + .create_with_contents("included in inputs") + .unwrap(); + + let watcher = FileSystemWatcher::new_with_default_cookie_dir(&repo_root).unwrap(); + + let recv = watcher.watch(); + let cookie_writer = CookieWriter::new( + watcher.cookie_dir(), + Duration::from_millis(100), + recv.clone(), + ); + + let scm = SCM::new(&repo_root); + assert!(!scm.is_manual()); + let package_watcher = PackageWatcher::new(repo_root.clone(), recv, cookie_writer).unwrap(); + let package_discovery = package_watcher.watch_discovery(); + let hash_watcher = + HashWatcher::new(repo_root.clone(), package_discovery, watcher.watch(), scm); + + let extra_foo_inputs = GlobSet::from_raw(vec!["out/*-file".to_string()], vec![]).unwrap(); + let foo_spec = HashSpec { + package_path: repo_root.anchor(&foo_path).unwrap(), + inputs: InputGlobs::DefaultWithExtras(extra_foo_inputs), + }; + + retry_get_hash( + &hash_watcher, + foo_spec.clone(), + Duration::from_secs(2), + make_expected(vec![ + ("foo-file", "9317666a2e7b729b740c706ab79724952c97bde4"), + ("package.json", "395351bdd7167f351af3396d3225ebe97a7a4d13"), + (".gitignore", "89f9ac04aac6c8ee66e158853e7d0439b3ec782d"), + ( + "out/ignored-file", + "e77845e6da275119a0a5a38dbb824773a45f66b3", + ), + ]), + ) + .await; + + // update ignored file + ignored_file_path + .create_with_contents("included in inputs again") + .unwrap(); + + retry_get_hash( + &hash_watcher, + foo_spec.clone(), + Duration::from_secs(2), + make_expected(vec![ + ("foo-file", "9317666a2e7b729b740c706ab79724952c97bde4"), + ("package.json", "395351bdd7167f351af3396d3225ebe97a7a4d13"), + (".gitignore", "89f9ac04aac6c8ee66e158853e7d0439b3ec782d"), + ( + "out/ignored-file", + "9fdccf172d999222f3b2103d99a8658de7b21fc6", + ), + ]), + ) + .await; + + // update foo-file + let foo_file_path = repo_root.join_components(&["packages", "foo", "foo-file"]); + foo_file_path + .create_with_contents("new foo-file contents") + .unwrap(); + retry_get_hash( + &hash_watcher, + foo_spec, + Duration::from_secs(2), + make_expected(vec![ + ("foo-file", "5f6796bbd23dcdc9d30d07a2d8a4817c34b7f1e7"), + ("package.json", "395351bdd7167f351af3396d3225ebe97a7a4d13"), + (".gitignore", "89f9ac04aac6c8ee66e158853e7d0439b3ec782d"), + ( + "out/ignored-file", + "9fdccf172d999222f3b2103d99a8658de7b21fc6", + ), + ]), + ) + .await; + } + + #[tokio::test] + #[tracing_test::traced_test] + async fn test_negative_inputs() { + let (_tmp, _repo, repo_root) = setup_fixture(); + + let watcher = FileSystemWatcher::new_with_default_cookie_dir(&repo_root).unwrap(); + + let recv = watcher.watch(); + let cookie_writer = CookieWriter::new( + watcher.cookie_dir(), + Duration::from_millis(100), + recv.clone(), + ); + + let scm = SCM::new(&repo_root); + assert!(!scm.is_manual()); + let package_watcher = PackageWatcher::new(repo_root.clone(), recv, cookie_writer).unwrap(); + let package_discovery = package_watcher.watch_discovery(); + let hash_watcher = + HashWatcher::new(repo_root.clone(), package_discovery, watcher.watch(), scm); + + let foo_path = repo_root.join_components(&["packages", "foo"]); + let dist_path = foo_path.join_component("dist"); + dist_path + .join_component("some-dist-file") + .create_with_contents("dist file") + .unwrap(); + dist_path + .join_component("extra-file") + .create_with_contents("extra file") + .unwrap(); + let foo_inputs = GlobSet::from_raw_unfiltered(vec![ + "!dist/extra-file".to_string(), + "**/*-file".to_string(), + ]) + .unwrap(); + let foo_spec = HashSpec { + package_path: repo_root.anchor(&foo_path).unwrap(), + inputs: InputGlobs::Specific(foo_inputs), + }; + + retry_get_hash( + &hash_watcher, + foo_spec.clone(), + Duration::from_secs(2), + make_expected(vec![ + ("foo-file", "9317666a2e7b729b740c706ab79724952c97bde4"), + ("package.json", "395351bdd7167f351af3396d3225ebe97a7a4d13"), + ( + "dist/some-dist-file", + "21aa527e5ea52d11bf53f493df0dbe6d659b6a30", + ), + ]), + ) + .await; + + dist_path + .join_component("some-dist-file") + .create_with_contents("new dist file contents") + .unwrap(); + retry_get_hash( + &hash_watcher, + foo_spec.clone(), + Duration::from_secs(2), + make_expected(vec![ + ("foo-file", "9317666a2e7b729b740c706ab79724952c97bde4"), + ("package.json", "395351bdd7167f351af3396d3225ebe97a7a4d13"), + ( + "dist/some-dist-file", + "03d4fc427f0bccc1ca7053fc889fa73e54a402fa", + ), + ]), + ) + .await; } } diff --git a/crates/turborepo-filewatch/src/lib.rs b/crates/turborepo-filewatch/src/lib.rs index 6fba08f2ca9b5..b89f877063eec 100644 --- a/crates/turborepo-filewatch/src/lib.rs +++ b/crates/turborepo-filewatch/src/lib.rs @@ -1,3 +1,25 @@ +//! File watching utilities for Turborepo. Includes a file watcher that is +//! designed to work across multiple platforms, with consistent behavior and +//! consistent ordering. +//! +//! Also includes watchers that take in file change events and produce derived +//! data like changed packages or the workspaces in a repository. +//! +//! ## Watcher Implementation +//! It's important to note that when implementing a watcher, you should aim to +//! make file change event processing as fast as possible. There should be +//! almost no slow code in the main event loop. Otherwise, the receiver will lag +//! behind, and return a `Lagged` event. +//! +//! A common pattern that we use to avoid lag is having a separate event thread +//! that processes events and accumulates them into a data structure, say a +//! `Trie` for changed files, or a `HashSet` for changed packages. From there, a +//! second thread is responsible for actually taking that accumulated data and +//! processing it. This second thread can do slower tasks like executing a run +//! or mapping files to changed packages. It can either be parked and awoken +//! using `tokio::sync::Notify` or it can run periodically using +//! `tokio::time::interval`. + #![deny(clippy::all)] #![feature(assert_matches)] @@ -35,6 +57,7 @@ use { }; pub mod cookies; +mod debouncer; #[cfg(target_os = "macos")] mod fsevent; pub mod globwatcher; diff --git a/crates/turborepo-filewatch/src/package_watcher.rs b/crates/turborepo-filewatch/src/package_watcher.rs index 758176e482d14..da35e9387410a 100644 --- a/crates/turborepo-filewatch/src/package_watcher.rs +++ b/crates/turborepo-filewatch/src/package_watcher.rs @@ -1,16 +1,24 @@ //! This module hosts the `PackageWatcher` type, which is used to watch the //! filesystem for changes to packages. -use std::{collections::HashMap, path::Path}; +use std::{ + collections::HashMap, + path::Path, + sync::{ + atomic::{AtomicUsize, Ordering}, + Arc, + }, + time::Duration, +}; use futures::FutureExt; use notify::Event; use thiserror::Error; use tokio::{ - join, + join, select, sync::{ broadcast::{self, error::RecvError}, - oneshot, watch, + mpsc, oneshot, watch, }, }; use turbopath::{AbsoluteSystemPath, AbsoluteSystemPathBuf}; @@ -24,6 +32,7 @@ use turborepo_repository::{ use crate::{ cookies::{CookieRegister, CookieWriter, CookiedOptionalWatch}, + debouncer::Debouncer, optional_watch::OptionalWatch, NotifyError, }; @@ -49,6 +58,17 @@ pub enum PackageWatchError { // making a change. pub(crate) type DiscoveryData = Result; +// Version is a type that exists to stamp an asynchronous hash computation +// with a version so that we can ignore completion of outdated hash +// computations. +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +struct Version(usize); + +struct DiscoveryResult { + version: Version, + state: PackageState, +} + /// Watches the filesystem for changes to packages and package managers. pub struct PackageWatcher { // _exit_ch exists to trigger a close on the receiver when an instance @@ -123,13 +143,14 @@ struct Subscriber { package_discovery_tx: watch::Sender>, package_discovery_lazy: CookiedOptionalWatch, cookie_tx: CookieRegister, + next_version: AtomicUsize, } /// PackageWatcher state. We either don't have a valid package manager, /// don't have valid globs, or we have both a package manager and globs /// and some maybe-empty set of workspaces. #[derive(Debug)] -enum State { +enum PackageState { NoPackageManager(String), InvalidGlobs(String), ValidWorkspaces { @@ -139,6 +160,15 @@ enum State { }, } +#[derive(Debug)] +enum State { + Pending { + debouncer: Arc, + version: Version, + }, + Ready(PackageState), +} + // Because our package manager detection is coupled with the workspace globs, we // need to recheck all workspaces any time any of these files change. A change // in any of these might result in a different package manager being detected, @@ -173,9 +203,37 @@ impl Subscriber { package_discovery_tx, package_discovery_lazy, cookie_tx, + next_version: AtomicUsize::new(0), }) } + fn queue_rediscovery( + &self, + immediate: bool, + package_state_tx: mpsc::Sender, + ) -> (Version, Arc) { + // Every time we're queuing rediscovery, we know our state is no longer valid, + // so reset it for any downstream consumers. + self.reset_discovery_data(); + let version = Version(self.next_version.fetch_add(1, Ordering::SeqCst)); + let debouncer = if immediate { + Debouncer::new(Duration::from_millis(0)) + } else { + Debouncer::default() + }; + let debouncer = Arc::new(debouncer); + let debouncer_copy = debouncer.clone(); + let repo_root = self.repo_root.clone(); + tokio::task::spawn(async move { + debouncer_copy.debounce().await; + let state = discover_packages(repo_root).await; + let _ = package_state_tx + .send(DiscoveryResult { version, state }) + .await; + }); + (version, debouncer) + } + async fn watch_process( mut self, mut recv: OptionalWatch>>, @@ -186,32 +244,56 @@ impl Subscriber { Err(e) => return PackageWatcherProcessError::Filewatching(e), }; - // state represents our current understanding of the underlying filesystem, and - // is expected to be mutated in place by handle_file_event. Both - // rediscover_everything and handle_file_event are responsible for - // broadcasting updates to state. - let mut state = self.rediscover_and_write_state().await; + let (package_state_tx, mut package_state_rx) = mpsc::channel::(256); + + let (version, debouncer) = self.queue_rediscovery(true, package_state_tx.clone()); + + // state represents the current state of this process, and is expected to be + // updated in place by the various handler functions. + let mut state = State::Pending { debouncer, version }; tracing::debug!("package watcher ready {:?}", state); loop { - let file_event = recv.recv().await; - match file_event { - Ok(Ok(event)) => self.handle_file_event(&mut state, &event).await, - // if we get an error, we need to re-discover the packages - Ok(Err(_)) => state = self.rediscover_and_write_state().await, - Err(e @ RecvError::Closed) => { - return PackageWatcherProcessError::FilewatchingClosed(e) - } - // if we end up lagging, warn and rediscover packages - Err(RecvError::Lagged(count)) => { - tracing::warn!("lagged behind {count} processing file watching events"); - state = self.rediscover_and_write_state().await; + select! { + Some(discovery_result) = package_state_rx.recv() => { + self.handle_discovery_result(discovery_result, &mut state); + }, + file_event = recv.recv() => { + match file_event { + Ok(Ok(event)) => self.handle_file_event(&mut state, &event, &package_state_tx).await, + // if we get an error, we need to re-discover the packages + Ok(Err(_)) => self.bump_or_queue_rediscovery(&mut state, &package_state_tx), + Err(e @ RecvError::Closed) => { + return PackageWatcherProcessError::FilewatchingClosed(e) + } + // if we end up lagging, warn and rediscover packages + Err(RecvError::Lagged(count)) => { + tracing::warn!("lagged behind {count} processing file watching events"); + self.bump_or_queue_rediscovery(&mut state, &package_state_tx); + } + } } } tracing::trace!("package watcher state: {:?}", state); } } + fn handle_discovery_result(&self, package_result: DiscoveryResult, state: &mut State) { + if let State::Pending { version, .. } = state { + // If this response matches an outstanding rediscovery request, write out the + // corresponding state to downstream consumers and update our state + // accordingly. + // + // Note that depending on events that we received since this request was queued, + // we may have a higher version number, at which point we would + // ignore this update, as we know it is stale. + if package_result.version == *version { + self.write_state(&package_result.state); + *state = State::Ready(package_result.state); + } + } + } + async fn watch( self, exit_rx: oneshot::Receiver<()>, @@ -243,7 +325,12 @@ impl Subscriber { .any(|invalidation_path| path.eq(invalidation_path as &AbsoluteSystemPath)) } - async fn handle_file_event(&mut self, state: &mut State, file_event: &Event) { + async fn handle_file_event( + &mut self, + state: &mut State, + file_event: &Event, + package_state_tx: &mpsc::Sender, + ) { tracing::trace!("file event: {:?} {:?}", file_event.kind, file_event.paths); if file_event @@ -252,10 +339,12 @@ impl Subscriber { .any(|path| self.path_invalidates_everything(path)) { // root package.json changed, rediscover everything - *state = self.rediscover_and_write_state().await; + //*state = self.rediscover_and_write_state().await; + self.bump_or_queue_rediscovery(state, package_state_tx); } else { tracing::trace!("handling non-root package.json change"); - self.handle_workspace_changes(state, file_event).await; + self.handle_workspace_changes(state, file_event, package_state_tx) + .await; } tracing::trace!("updating the cookies"); @@ -271,14 +360,48 @@ impl Subscriber { ); } + fn bump_or_queue_rediscovery( + &self, + state: &mut State, + package_state_tx: &mpsc::Sender, + ) { + if let State::Pending { debouncer, .. } = state { + if debouncer.bump() { + // We successfully bumped the debouncer, which was already pending, + // so a new discovery will happen shortly. + return; + } + } + // We either failed to bump the debouncer, or we don't have a rediscovery + // queued, but we need one. + let (version, debouncer) = self.queue_rediscovery(false, package_state_tx.clone()); + *state = State::Pending { debouncer, version } + } + // checks if the file event contains any changes to package.json files, or // directories that would map to a workspace. - async fn handle_workspace_changes(&mut self, state: &mut State, file_event: &Event) { + async fn handle_workspace_changes( + &mut self, + state: &mut State, + file_event: &Event, + package_state_tx: &mpsc::Sender, + ) { + let package_state = match state { + State::Pending { .. } => { + // We can't assess this event until we have a valid package manager. To be safe, + // bump or queue another rediscovery, since this could race with the discovery + // in progress. + self.bump_or_queue_rediscovery(state, package_state_tx); + return; + } + State::Ready(package_state) => package_state, + }; + // If we don't have a valid package manager and workspace globs, nothing to be // done here - let State::ValidWorkspaces { + let PackageState::ValidWorkspaces { filter, workspaces, .. - } = state + } = package_state else { return; }; @@ -347,7 +470,7 @@ impl Subscriber { } if changed { - self.write_state(state); + self.write_state(package_state); } } @@ -362,59 +485,9 @@ impl Subscriber { }); } - async fn rediscover_and_write_state(&mut self) -> State { - // If we're rediscovering the package manager, clear all data - self.reset_discovery_data(); - let state = self.rediscover().await; - self.write_state(&state); - state - } - - async fn rediscover(&self) -> State { - // If we're rediscovering everything, we need to rediscover the package manager. - // It may have changed if a lockfile changed or package.json changed. - let discovery = - match LocalPackageDiscoveryBuilder::new(self.repo_root.clone(), None, None).build() { - Ok(discovery) => discovery, - Err(e) => return State::NoPackageManager(e.to_string()), - }; - let initial_discovery = match discovery.discover_packages().await { - Ok(discovery) => discovery, - // If we failed the discovery, that's fine, we've reset the values, leave them as None - Err(e) => { - tracing::debug!("failed to rediscover packages: {}", e); - return State::NoPackageManager(e.to_string()); - } - }; - - tracing::debug!("rediscovered packages: {:?}", initial_discovery); - let filter = match initial_discovery - .package_manager - .get_workspace_globs(&self.repo_root) - { - Ok(filter) => filter, - Err(e) => { - // If the globs are invalid, leave everything set to None - tracing::debug!("failed to get workspace globs: {}", e); - return State::InvalidGlobs(e.to_string()); - } - }; - - let workspaces = initial_discovery - .workspaces - .into_iter() - .map(|p| (p.package_json.parent().expect("non-root").to_owned(), p)) - .collect::>(); - State::ValidWorkspaces { - package_manager: initial_discovery.package_manager, - filter, - workspaces, - } - } - - fn write_state(&self, state: &State) { + fn write_state(&self, state: &PackageState) { match state { - State::NoPackageManager(e) | State::InvalidGlobs(e) => { + PackageState::NoPackageManager(e) | PackageState::InvalidGlobs(e) => { self.package_discovery_tx.send_if_modified(|existing| { let error_msg = e.to_string(); match existing { @@ -426,7 +499,7 @@ impl Subscriber { } }); } - State::ValidWorkspaces { + PackageState::ValidWorkspaces { package_manager, workspaces, .. @@ -443,6 +516,45 @@ impl Subscriber { } } +async fn discover_packages(repo_root: AbsoluteSystemPathBuf) -> PackageState { + // If we're rediscovering everything, we need to rediscover the package manager. + // It may have changed if a lockfile changed or package.json changed. + let discovery = match LocalPackageDiscoveryBuilder::new(repo_root.clone(), None, None).build() { + Ok(discovery) => discovery, + Err(e) => return PackageState::NoPackageManager(e.to_string()), + }; + let initial_discovery = match discovery.discover_packages().await { + Ok(discovery) => discovery, + Err(e) => { + tracing::debug!("failed to rediscover packages: {}", e); + return PackageState::NoPackageManager(e.to_string()); + } + }; + + tracing::debug!("rediscovered packages: {:?}", initial_discovery); + let filter = match initial_discovery + .package_manager + .get_workspace_globs(&repo_root) + { + Ok(filter) => filter, + Err(e) => { + tracing::debug!("failed to get workspace globs: {}", e); + return PackageState::InvalidGlobs(e.to_string()); + } + }; + + let workspaces = initial_discovery + .workspaces + .into_iter() + .map(|p| (p.package_json.parent().expect("non-root").to_owned(), p)) + .collect::>(); + PackageState::ValidWorkspaces { + package_manager: initial_discovery.package_manager, + filter, + workspaces, + } +} + #[cfg(test)] mod test { use std::time::Duration; diff --git a/crates/turborepo-lib/Cargo.toml b/crates/turborepo-lib/Cargo.toml index 3bb9525c3279d..041a1fd31e9a5 100644 --- a/crates/turborepo-lib/Cargo.toml +++ b/crates/turborepo-lib/Cargo.toml @@ -81,6 +81,7 @@ pprof = { version = "0.12.1", features = [ "frame-pointer", ], optional = true } prost = "0.12.3" +radix_trie = { workspace = true } rand = { workspace = true } rayon = "1.7.0" regex.workspace = true diff --git a/crates/turborepo-lib/src/cli/mod.rs b/crates/turborepo-lib/src/cli/mod.rs index dbf3438c82dde..dd9dc72a7a1c7 100644 --- a/crates/turborepo-lib/src/cli/mod.rs +++ b/crates/turborepo-lib/src/cli/mod.rs @@ -1286,7 +1286,8 @@ pub async fn run( event.track_call(); let base = CommandBase::new(cli_args, repo_root, version, ui); - WatchClient::start(base, event).await?; + let mut client = WatchClient::new(base, event).await?; + client.start().await?; // We only exit if we get a signal, so we return a non-zero exit code return Ok(1); } diff --git a/crates/turborepo-lib/src/commands/mod.rs b/crates/turborepo-lib/src/commands/mod.rs index 36be65664fe4e..e20e860ee43dd 100644 --- a/crates/turborepo-lib/src/commands/mod.rs +++ b/crates/turborepo-lib/src/commands/mod.rs @@ -1,4 +1,4 @@ -use std::cell::OnceCell; +use std::{cell::OnceCell, time::Duration}; use turbopath::{AbsoluteSystemPath, AbsoluteSystemPathBuf}; use turborepo_api_client::{APIAuth, APIClient}; @@ -125,9 +125,24 @@ impl CommandBase { let config = self.config()?; let api_url = config.api_url(); let timeout = config.timeout(); - - APIClient::new(api_url, timeout, self.version, config.preflight()) - .map_err(ConfigError::ApiClient) + let upload_timeout = config.upload_timeout(); + + APIClient::new( + api_url, + if timeout > 0 { + Some(Duration::from_secs(timeout)) + } else { + None + }, + if upload_timeout > 0 { + Some(Duration::from_secs(upload_timeout)) + } else { + None + }, + self.version, + config.preflight(), + ) + .map_err(ConfigError::ApiClient) } /// Current working directory for the turbo command diff --git a/crates/turborepo-lib/src/commands/run.rs b/crates/turborepo-lib/src/commands/run.rs index 09690d00250ec..89e51d5964165 100644 --- a/crates/turborepo-lib/src/commands/run.rs +++ b/crates/turborepo-lib/src/commands/run.rs @@ -1,5 +1,6 @@ use std::future::Future; +use tracing::error; use turborepo_telemetry::events::command::CommandEventBuilder; use crate::{commands::CommandBase, run, run::builder::RunBuilder, signal::SignalHandler}; @@ -42,12 +43,22 @@ pub async fn run(base: CommandBase, telemetry: CommandEventBuilder) -> Result, pub(crate) preflight: Option, pub(crate) timeout: Option, + pub(crate) upload_timeout: Option, pub(crate) enabled: Option, pub(crate) spaces_id: Option, #[serde(rename = "experimentalUI")] @@ -234,10 +238,16 @@ impl ConfigurationOptions { self.preflight.unwrap_or_default() } + /// Note: 0 implies no timeout pub fn timeout(&self) -> u64 { self.timeout.unwrap_or(DEFAULT_TIMEOUT) } + /// Note: 0 implies no timeout + pub fn upload_timeout(&self) -> u64 { + self.upload_timeout.unwrap_or(DEFAULT_UPLOAD_TIMEOUT) + } + pub fn spaces_id(&self) -> Option<&str> { self.spaces_id.as_deref() } @@ -312,6 +322,7 @@ fn get_env_var_config( turbo_mapping.insert(OsString::from("turbo_teamid"), "team_id"); turbo_mapping.insert(OsString::from("turbo_token"), "token"); turbo_mapping.insert(OsString::from("turbo_remote_cache_timeout"), "timeout"); + turbo_mapping.insert(OsString::from("turbo_api_timeout"), "api_timeout"); turbo_mapping.insert(OsString::from("turbo_experimental_ui"), "experimental_ui"); turbo_mapping.insert(OsString::from("turbo_preflight"), "preflight"); @@ -383,6 +394,16 @@ fn get_env_var_config( None }; + let upload_timeout = if let Some(upload_timeout) = output_map.get("upload_timeout") { + Some( + upload_timeout + .parse::() + .map_err(Error::InvalidUploadTimeout)?, + ) + } else { + None + }; + // Process experimentalUI let experimental_ui = output_map .get("experimental_ui") @@ -412,6 +433,7 @@ fn get_env_var_config( // Processed numbers timeout, + upload_timeout, spaces_id, }; @@ -457,6 +479,7 @@ fn get_override_env_var_config( enabled: None, experimental_ui: None, timeout: None, + upload_timeout: None, spaces_id: None, }; diff --git a/crates/turborepo-lib/src/daemon/server.rs b/crates/turborepo-lib/src/daemon/server.rs index 5d7cf52c9bb31..675865d877ad3 100644 --- a/crates/turborepo-lib/src/daemon/server.rs +++ b/crates/turborepo-lib/src/daemon/server.rs @@ -18,7 +18,7 @@ use semver::Version; use thiserror::Error; use tokio::{ select, - sync::{mpsc, oneshot}, + sync::{broadcast::error::RecvError, mpsc, oneshot}, task::JoinHandle, }; use tokio_stream::wrappers::ReceiverStream; @@ -29,7 +29,7 @@ use turbopath::{AbsoluteSystemPath, AbsoluteSystemPathBuf, AnchoredSystemPathBuf use turborepo_filewatch::{ cookies::CookieWriter, globwatcher::{Error as GlobWatcherError, GlobError, GlobSet, GlobWatcher}, - hash_watcher::{Error as HashWatcherError, HashSpec, HashWatcher}, + hash_watcher::{Error as HashWatcherError, HashSpec, HashWatcher, InputGlobs}, package_watcher::{PackageWatchError, PackageWatcher}, FileSystemWatcher, WatchError, }; @@ -136,7 +136,11 @@ impl FileWatching { scm, )); - let package_changes_watcher = Arc::new(PackageChangesWatcher::new(repo_root, recv.clone())); + let package_changes_watcher = Arc::new(PackageChangesWatcher::new( + repo_root, + recv.clone(), + hash_watcher.clone(), + )); Ok(FileWatching { watcher, @@ -359,16 +363,12 @@ impl TurboGrpcServiceInner { package_path: String, inputs: Vec, ) -> Result, RpcError> { - let glob_set = if inputs.is_empty() { - None - } else { - Some(GlobSet::from_raw_unfiltered(inputs)?) - }; + let inputs = InputGlobs::from_raw(inputs)?; let package_path = AnchoredSystemPathBuf::try_from(package_path.as_str()) .map_err(|e| RpcError::InvalidAnchoredPath(package_path, e))?; let hash_spec = HashSpec { package_path, - inputs: glob_set, + inputs, }; self.file_watching .hash_watcher @@ -594,7 +594,8 @@ impl proto::turbod_server::Turbod for TurboGrpcServiceInner { .package_changes_watcher .package_changes() .await; - let (tx, rx) = mpsc::channel(1); + + let (tx, rx) = mpsc::channel(1024); tx.send(Ok(proto::PackageChangeEvent { event: Some(proto::package_change_event::Event::RediscoverPackages( @@ -607,6 +608,14 @@ impl proto::turbod_server::Turbod for TurboGrpcServiceInner { tokio::spawn(async move { loop { let event = match package_changes_rx.recv().await { + Err(RecvError::Lagged(_)) => { + warn!("package changes stream lagged"); + proto::PackageChangeEvent { + event: Some(proto::package_change_event::Event::RediscoverPackages( + proto::RediscoverPackages {}, + )), + } + } Err(err) => proto::PackageChangeEvent { event: Some(proto::package_change_event::Event::Error( proto::PackageChangeError { diff --git a/crates/turborepo-lib/src/engine/mod.rs b/crates/turborepo-lib/src/engine/mod.rs index 40f6539685263..0b254246f2e4f 100644 --- a/crates/turborepo-lib/src/engine/mod.rs +++ b/crates/turborepo-lib/src/engine/mod.rs @@ -142,11 +142,15 @@ impl Engine { /// Creates an instance of `Engine` that only contains tasks that depend on /// tasks from a given package. This is useful for watch mode, where we /// need to re-run only a portion of the task graph. - pub fn create_engine_for_subgraph(&self, changed_package: &PackageName) -> Engine { - let entrypoint_indices: &[petgraph::graph::NodeIndex] = self - .package_tasks - .get(changed_package) - .map_or(&[], |v| &v[..]); + pub fn create_engine_for_subgraph( + &self, + changed_packages: &HashSet, + ) -> Engine { + let entrypoint_indices: Vec<_> = changed_packages + .iter() + .flat_map(|pkg| self.package_tasks.get(pkg)) + .flatten() + .collect(); // We reverse the graph because we want the *dependents* of entrypoint tasks let mut reversed_graph = self.task_graph.clone(); @@ -175,7 +179,7 @@ impl Engine { .iter() .any(|idx| { node_distances - .get(&(*idx, node_idx)) + .get(&(**idx, node_idx)) .map_or(false, |dist| *dist != i32::MAX) }) .then_some(node.clone()) @@ -293,7 +297,7 @@ impl Engine { continue; } - new_graph.add_edge(root_index, index, ()); + new_graph.add_edge(index, root_index, ()); } let task_lookup: HashMap<_, _> = new_graph @@ -764,7 +768,8 @@ mod test { engine.task_graph.add_edge(b_build_idx, a_build_idx, ()); let engine = engine.seal(); - let subgraph = engine.create_engine_for_subgraph(&PackageName::from("a")); + let subgraph = + engine.create_engine_for_subgraph(&[PackageName::from("a")].into_iter().collect()); // Verify that the subgraph only contains tasks from package `a` and the `build` // task from package `b` diff --git a/crates/turborepo-lib/src/package_changes_watcher.rs b/crates/turborepo-lib/src/package_changes_watcher.rs index ef1f25cf3fd1e..3e05ed46cd08e 100644 --- a/crates/turborepo-lib/src/package_changes_watcher.rs +++ b/crates/turborepo-lib/src/package_changes_watcher.rs @@ -1,15 +1,25 @@ -use std::collections::HashSet; +use std::{ + cell::RefCell, + collections::{HashMap, HashSet}, + ops::DerefMut, + sync::Arc, +}; use ignore::gitignore::Gitignore; use notify::Event; -use tokio::sync::{broadcast, oneshot}; +use radix_trie::{Trie, TrieCommon}; +use tokio::sync::{broadcast, oneshot, Mutex}; use turbopath::{AbsoluteSystemPathBuf, AnchoredSystemPath, AnchoredSystemPathBuf}; -use turborepo_filewatch::{NotifyError, OptionalWatch}; +use turborepo_filewatch::{ + hash_watcher::{HashSpec, HashWatcher, InputGlobs}, + NotifyError, OptionalWatch, +}; use turborepo_repository::{ change_mapper::{ChangeMapper, GlobalDepsPackageChangeMapper, PackageChanges}, package_graph::{PackageGraph, PackageGraphBuilder, PackageName, WorkspacePackage}, package_json::PackageJson, }; +use turborepo_scm::package_deps::GitHashes; use crate::turbo_json::TurboJson; @@ -34,11 +44,17 @@ impl PackageChangesWatcher { pub fn new( repo_root: AbsoluteSystemPathBuf, file_events_lazy: OptionalWatch>>, + hash_watcher: Arc, ) -> Self { let (exit_tx, exit_rx) = oneshot::channel(); let (package_change_events_tx, package_change_events_rx) = broadcast::channel(CHANGE_EVENT_CHANNEL_CAPACITY); - let subscriber = Subscriber::new(repo_root, file_events_lazy, package_change_events_tx); + let subscriber = Subscriber::new( + repo_root, + file_events_lazy, + package_change_events_tx, + hash_watcher, + ); let _handle = tokio::spawn(subscriber.watch(exit_rx)); Self { @@ -53,10 +69,33 @@ impl PackageChangesWatcher { } } +enum ChangedFiles { + All, + // Trie doesn't support PathBuf as a key on Windows, so we need to use `String` + Some(Trie), +} + +impl ChangedFiles { + fn is_empty(&self) -> bool { + match self { + ChangedFiles::All => false, + ChangedFiles::Some(trie) => trie.is_empty(), + } + } +} + +impl Default for ChangedFiles { + fn default() -> Self { + ChangedFiles::Some(Trie::new()) + } +} + struct Subscriber { file_events_lazy: OptionalWatch>>, + changed_files: Mutex>, repo_root: AbsoluteSystemPathBuf, package_change_events_tx: broadcast::Sender, + hash_watcher: Arc, } // This is a workaround because `ignore` doesn't match against a path's @@ -104,15 +143,18 @@ impl Subscriber { repo_root: AbsoluteSystemPathBuf, file_events_lazy: OptionalWatch>>, package_change_events_tx: broadcast::Sender, + hash_watcher: Arc, ) -> Self { Subscriber { repo_root, file_events_lazy, + changed_files: Default::default(), package_change_events_tx, + hash_watcher, } } - async fn initialize_repo_state(&mut self) -> Option { + async fn initialize_repo_state(&self) -> Option<(RepoState, Gitignore)> { let Ok(root_package_json) = PackageJson::load(&self.repo_root.join_component("package.json")) else { @@ -128,6 +170,9 @@ impl Subscriber { ) .ok(); + let gitignore_path = self.repo_root.join_component(".gitignore"); + let (root_gitignore, _) = Gitignore::new(&gitignore_path); + let Ok(pkg_dep_graph) = PackageGraphBuilder::new(&self.repo_root, root_package_json) .build() .await @@ -136,26 +181,97 @@ impl Subscriber { return None; }; - Some(RepoState { - root_turbo_json, - pkg_dep_graph, - }) + Some(( + RepoState { + root_turbo_json, + pkg_dep_graph, + }, + root_gitignore, + )) + } + + async fn is_same_hash( + &self, + pkg: &WorkspacePackage, + package_file_hashes: &mut HashMap, + ) -> bool { + let Ok(hash) = self + .hash_watcher + .get_file_hashes(HashSpec { + package_path: pkg.path.clone(), + // TODO: Support inputs + inputs: InputGlobs::Default, + }) + .await + else { + return false; + }; + + let old_hash = package_file_hashes.get(&pkg.path).cloned(); + + if Some(&hash) != old_hash.as_ref() { + package_file_hashes.insert(pkg.path.clone(), hash); + return false; + } + + tracing::warn!("hashes are the same, no need to rerun"); + + true } async fn watch(mut self, exit_rx: oneshot::Receiver<()>) { - let process = async { + let Ok(mut file_events) = self.file_events_lazy.get().await.map(|r| r.resubscribe()) else { + // if we get here, it means that file watching has not started, so we should + // just report that the package watcher is not available + tracing::debug!("file watching shut down, package watcher not available"); + return; + }; + + // This just processes the events and puts the changed files into a `Trie`. + // Must be fast to avoid lagging the file events channel. + let event_fut = async { + loop { + match file_events.recv().await { + Ok(Ok(Event { paths, .. })) => { + if let ChangedFiles::Some(trie) = + self.changed_files.lock().await.borrow_mut().deref_mut() + { + for path in paths { + if let Some(path) = path.to_str() { + trie.insert(path.to_string(), ()); + } + } + } + } + Ok(Err(err)) => { + tracing::error!("file event error: {:?}", err); + break; + } + Err(broadcast::error::RecvError::Lagged(_)) => { + tracing::warn!("file event lagged"); + // Lagged essentially means we're not keeping up with + // the file events, so + // we can catch up by declaring all files changed + *self.changed_files.lock().await.borrow_mut() = ChangedFiles::All; + } + Err(broadcast::error::RecvError::Closed) => { + tracing::debug!("file event channel closed"); + break; + } + } + } + }; + + let changes_fut = async { let root_pkg = WorkspacePackage::root(); - let Ok(mut file_events) = self.file_events_lazy.get().await.map(|r| r.resubscribe()) - else { - // if we get here, it means that file watching has not started, so we should - // just report that the package watcher is not available - tracing::debug!("file watching shut down, package watcher not available"); - return; - }; - let Some(mut repo_state) = self.initialize_repo_state().await else { + let Some((mut repo_state, mut root_gitignore)) = self.initialize_repo_state().await + else { return; }; + // We store the hash of the package's files. If the hash is already + // in here, we don't need to recompute it + let mut package_file_hashes = HashMap::new(); let mut change_mapper = match repo_state.get_change_mapper() { Some(change_mapper) => change_mapper, @@ -167,121 +283,139 @@ impl Subscriber { self.package_change_events_tx .send(PackageChangeEvent::Rediscover) .ok(); + let mut interval = tokio::time::interval(std::time::Duration::from_millis(100)); loop { - match file_events.recv().await { - Ok(Ok(Event { paths, .. })) => { - // No point in raising an error for an invalid .gitignore - // This is slightly incorrect because we should also search for the - // .gitignore files in the workspaces. - let (root_gitignore, _) = - Gitignore::new(&self.repo_root.join_component(".gitignore")); - - let changed_files: HashSet<_> = paths - .into_iter() - .filter_map(|p| { - let p = AbsoluteSystemPathBuf::try_from(p).ok()?; - self.repo_root.anchor(p).ok() - }) - .filter(|p| { - // If in .gitignore or in .git, filter out - !(ancestors_is_ignored(&root_gitignore, p) || is_in_git_folder(p)) - }) - .collect(); - - let changes = change_mapper.changed_packages(changed_files.clone(), None); - - match changes { - Ok(PackageChanges::All) => { - // We tell the client that we need to rediscover the packages, i.e. - // all bets are off, just re-run everything - let _ = self - .package_change_events_tx - .send(PackageChangeEvent::Rediscover); - match self.initialize_repo_state().await { - Some(new_repo_state) => { - repo_state = new_repo_state; - change_mapper = match repo_state.get_change_mapper() { - Some(change_mapper) => change_mapper, - None => { - break; - } - }; - } - None => { - break; - } - } - } - Ok(PackageChanges::Some(mut changed_pkgs)) => { - if !changed_pkgs.is_empty() { - tracing::debug!( - "changed files: {:?} changed packages: {:?}", - changed_files, - changed_pkgs - ); - } + interval.tick().await; + let changed_files = { + let changed_files = self.changed_files.lock().await; + if changed_files.borrow().is_empty() { + continue; + } - // If the root package has changed, we only send it if we have root - // tasks. Otherwise it's not worth sending as it will only - // pollute up the output logs - if changed_pkgs.contains(&root_pkg) { - let has_root_tasks = repo_state - .root_turbo_json - .as_ref() - .map_or(false, |turbo| turbo.has_root_tasks()); - if !has_root_tasks { - changed_pkgs.remove(&root_pkg); - } - } + changed_files.take() + }; + + let ChangedFiles::Some(trie) = changed_files else { + let _ = self + .package_change_events_tx + .send(PackageChangeEvent::Rediscover); - for pkg in changed_pkgs { - let _ = self.package_change_events_tx.send( - PackageChangeEvent::Package { - name: pkg.name.clone(), - }, - ); + match self.initialize_repo_state().await { + Some((new_repo_state, new_gitignore)) => { + repo_state = new_repo_state; + root_gitignore = new_gitignore; + change_mapper = match repo_state.get_change_mapper() { + Some(change_mapper) => change_mapper, + None => { + break; } - } - Err(err) => { - // Log the error, rediscover the packages and try again - tracing::error!("error: {:?}", err); - - let _ = self - .package_change_events_tx - .send(PackageChangeEvent::Rediscover); - match self.initialize_repo_state().await { - Some(new_repo_state) => { - repo_state = new_repo_state; - change_mapper = match repo_state.get_change_mapper() { - Some(change_mapper) => change_mapper, - None => { - break; - } - } - } + }; + } + None => { + break; + } + } + continue; + }; + + let gitignore_path = self.repo_root.join_component(".gitignore"); + if trie.get(gitignore_path.as_str()).is_some() { + let (new_root_gitignore, _) = Gitignore::new(&gitignore_path); + root_gitignore = new_root_gitignore; + } + + let changed_files: HashSet<_> = trie + .keys() + .filter_map(|p| { + let p = AbsoluteSystemPathBuf::new(p) + .expect("file watching should return absolute paths"); + self.repo_root.anchor(p).ok() + }) + .filter(|p| { + // If in .gitignore or in .git, filter out + !(ancestors_is_ignored(&root_gitignore, p) || is_in_git_folder(p)) + }) + .collect(); + + if changed_files.is_empty() { + continue; + } + + let changed_packages = change_mapper.changed_packages(changed_files.clone(), None); + + tracing::warn!("changed_files: {:?}", changed_files); + tracing::warn!("changed_packages: {:?}", changed_packages); + + match changed_packages { + Ok(PackageChanges::All) => { + // We tell the client that we need to rediscover the packages, i.e. + // all bets are off, just re-run everything + let _ = self + .package_change_events_tx + .send(PackageChangeEvent::Rediscover); + match self.initialize_repo_state().await { + Some((new_repo_state, new_gitignore)) => { + repo_state = new_repo_state; + root_gitignore = new_gitignore; + change_mapper = match repo_state.get_change_mapper() { + Some(change_mapper) => change_mapper, None => { break; } - } + }; + } + None => { + break; } } } - Ok(Err(err)) => { - tracing::error!("file event error: {:?}", err); - break; + Ok(PackageChanges::Some(mut filtered_pkgs)) => { + // If the root package has changed, we only send it if we have root + // tasks. Otherwise it's not worth sending as it will only + // pollute up the output logs + if filtered_pkgs.contains(&root_pkg) { + let has_root_tasks = repo_state + .root_turbo_json + .as_ref() + .map_or(false, |turbo| turbo.has_root_tasks()); + if !has_root_tasks { + filtered_pkgs.remove(&root_pkg); + } + } + + for pkg in filtered_pkgs { + if !self.is_same_hash(&pkg, &mut package_file_hashes).await { + let _ = self.package_change_events_tx.send( + PackageChangeEvent::Package { + name: pkg.name.clone(), + }, + ); + } + } } - Err(broadcast::error::RecvError::Lagged(_)) => { - tracing::warn!("file event lagged"); - // Lagged essentially means we're not keeping up with the file events, so - // we can catch up by sending a rediscover event + Err(err) => { + // Log the error, rediscover the packages and try again + tracing::error!("error: {:?}", err); + let _ = self .package_change_events_tx .send(PackageChangeEvent::Rediscover); - } - Err(broadcast::error::RecvError::Closed) => { - tracing::debug!("file event channel closed"); - break; + match self.initialize_repo_state().await { + Some((new_repo_state, new_gitignore)) => { + repo_state = new_repo_state; + root_gitignore = new_gitignore; + change_mapper = match repo_state.get_change_mapper() { + Some(change_mapper) => change_mapper, + None => { + break; + } + } + } + None => { + break; + } + } } } } @@ -292,7 +426,10 @@ impl Subscriber { _ = exit_rx => { tracing::debug!("exiting package changes watcher due to signal"); }, - _ = process => { + _ = event_fut => { + tracing::debug!("exiting package changes watcher due to file event end"); + }, + _ = changes_fut => { tracing::debug!("exiting package changes watcher due to process end"); } } diff --git a/crates/turborepo-lib/src/run/builder.rs b/crates/turborepo-lib/src/run/builder.rs index 1caff844e8fa5..2eb49f335dde8 100644 --- a/crates/turborepo-lib/src/run/builder.rs +++ b/crates/turborepo-lib/src/run/builder.rs @@ -62,7 +62,7 @@ pub struct RunBuilder { // In watch mode, we can have a changed package that we want to serve as an entrypoint. // We will then prune away any tasks that do not depend on tasks inside // this package. - entrypoint_package: Option, + entrypoint_packages: Option>, should_print_prelude_override: Option, } @@ -114,13 +114,13 @@ impl RunBuilder { version, experimental_ui, analytics_sender: None, - entrypoint_package: None, + entrypoint_packages: None, should_print_prelude_override: None, }) } - pub fn with_entrypoint_package(mut self, entrypoint_package: PackageName) -> Self { - self.entrypoint_package = Some(entrypoint_package); + pub fn with_entrypoint_packages(mut self, entrypoint_packages: HashSet) -> Self { + self.entrypoint_packages = Some(entrypoint_packages); self } @@ -451,8 +451,8 @@ impl RunBuilder { // If we have an initial task, we prune out the engine to only // tasks that are reachable from that initial task. - if let Some(entrypoint_package) = &self.entrypoint_package { - engine = engine.create_engine_for_subgraph(entrypoint_package); + if let Some(entrypoint_packages) = &self.entrypoint_packages { + engine = engine.create_engine_for_subgraph(entrypoint_packages); } if !self.opts.run_opts.parallel { diff --git a/crates/turborepo-lib/src/run/cache.rs b/crates/turborepo-lib/src/run/cache.rs index 91d7ef0490723..d4e50b9074783 100644 --- a/crates/turborepo-lib/src/run/cache.rs +++ b/crates/turborepo-lib/src/run/cache.rs @@ -8,7 +8,7 @@ use turborepo_cache::{AsyncCache, CacheError, CacheHitMetadata, CacheSource}; use turborepo_repository::package_graph::PackageInfo; use turborepo_scm::SCM; use turborepo_telemetry::events::{task::PackageTaskEventBuilder, TrackedErrors}; -use turborepo_ui::{color, replay_logs, ColorSelector, LogWriter, GREY, UI}; +use turborepo_ui::{color, ColorSelector, LogWriter, GREY, UI}; use crate::{ cli::OutputLogsMode, @@ -50,6 +50,13 @@ pub struct RunCache { ui: UI, } +/// Trait used to output cache information to user +pub trait CacheOutput { + fn status(&mut self, message: &str); + fn error(&mut self, message: &str); + fn replay_logs(&mut self, log_file: &AbsoluteSystemPath) -> Result<(), turborepo_ui::Error>; +} + impl RunCache { pub fn new( cache: AsyncCache, @@ -134,23 +141,20 @@ pub struct TaskCache { impl TaskCache { /// Will read log file and write to output a line at a time - pub fn replay_log_file(&self, output: impl Write) -> Result<(), Error> { + pub fn replay_log_file(&self, output: &mut impl CacheOutput) -> Result<(), Error> { if self.log_file_path.exists() { - replay_logs(output, &self.log_file_path)?; + output.replay_logs(&self.log_file_path)?; } Ok(()) } - pub fn on_error(&self, mut terminal_output: impl Write) -> Result<(), Error> { + pub fn on_error(&self, terminal_output: &mut impl CacheOutput) -> Result<(), Error> { if self.task_output_mode == OutputLogsMode::ErrorsOnly { - fallible_write( - &mut terminal_output, - &format!( - "cache miss, executing {}\n", - color!(self.ui, GREY, "{}", self.hash) - ), - ); + terminal_output.status(&format!( + "cache miss, executing {}", + color!(self.ui, GREY, "{}", self.hash) + )); self.replay_log_file(terminal_output)?; } @@ -183,8 +187,7 @@ impl TaskCache { pub async fn restore_outputs( &mut self, - mut terminal_output: impl Write, - alternative_log_replay: Option, + terminal_output: &mut impl CacheOutput, telemetry: &PackageTaskEventBuilder, ) -> Result, Error> { if self.caching_disabled || self.run_cache.reads_disabled { @@ -192,13 +195,10 @@ impl TaskCache { self.task_output_mode, OutputLogsMode::None | OutputLogsMode::ErrorsOnly ) { - fallible_write( - &mut terminal_output, - &format!( - "cache bypass, force executing {}\n", - color!(self.ui, GREY, "{}", self.hash) - ), - ); + terminal_output.status(&format!( + "cache bypass, force executing {}", + color!(self.ui, GREY, "{}", self.hash) + )); } return Ok(None); @@ -243,13 +243,10 @@ impl TaskCache { self.task_output_mode, OutputLogsMode::None | OutputLogsMode::ErrorsOnly ) { - fallible_write( - &mut terminal_output, - &format!( - "cache miss, executing {}\n", - color!(self.ui, GREY, "{}", self.hash) - ), - ); + terminal_output.status(&format!( + "cache miss, executing {}", + color!(self.ui, GREY, "{}", self.hash) + )); } return Ok(None); @@ -294,30 +291,20 @@ impl TaskCache { match self.task_output_mode { OutputLogsMode::HashOnly | OutputLogsMode::NewOnly => { - fallible_write( - &mut terminal_output, - &format!( - "cache hit{}, suppressing logs {}\n", - more_context, - color!(self.ui, GREY, "{}", self.hash) - ), - ); + terminal_output.status(&format!( + "cache hit{}, suppressing logs {}", + more_context, + color!(self.ui, GREY, "{}", self.hash) + )); } OutputLogsMode::Full => { debug!("log file path: {}", self.log_file_path); - fallible_write( - &mut terminal_output, - &format!( - "cache hit{}, replaying logs {}\n", - more_context, - color!(self.ui, GREY, "{}", self.hash) - ), - ); - if let Some(mut replay_writer) = alternative_log_replay { - self.replay_log_file(&mut replay_writer)?; - } else { - self.replay_log_file(&mut terminal_output)?; - } + terminal_output.status(&format!( + "cache hit{}, replaying logs {}", + more_context, + color!(self.ui, GREY, "{}", self.hash) + )); + self.replay_log_file(terminal_output)?; } // Note that if we're restoring from cache, the task succeeded // so we know we don't need to print anything for errors diff --git a/crates/turborepo-lib/src/run/mod.rs b/crates/turborepo-lib/src/run/mod.rs index 1b388478593b3..2e73d7a48cffd 100644 --- a/crates/turborepo-lib/src/run/mod.rs +++ b/crates/turborepo-lib/src/run/mod.rs @@ -14,18 +14,19 @@ pub mod watch; use std::{collections::HashSet, io::Write, sync::Arc}; -pub use cache::{ConfigCache, RunCache, TaskCache}; +pub use cache::{CacheOutput, ConfigCache, Error as CacheError, RunCache, TaskCache}; use chrono::{DateTime, Local}; use rayon::iter::ParallelBridge; +use tokio::task::JoinHandle; use tracing::debug; use turbopath::AbsoluteSystemPathBuf; use turborepo_api_client::{APIAuth, APIClient}; use turborepo_ci::Vendor; use turborepo_env::EnvironmentVariableMap; -use turborepo_repository::package_graph::{PackageGraph, PackageName}; +use turborepo_repository::package_graph::{PackageGraph, PackageName, PackageNode}; use turborepo_scm::SCM; use turborepo_telemetry::events::generic::GenericEventBuilder; -use turborepo_ui::{cprint, cprintln, BOLD_GREY, GREY, UI}; +use turborepo_ui::{cprint, cprintln, tui, tui::AppSender, BOLD_GREY, GREY, UI}; pub use crate::run::error::Error; use crate::{ @@ -45,7 +46,6 @@ use crate::{ pub struct Run { version: &'static str, ui: UI, - experimental_ui: bool, start_at: DateTime, processes: ProcessManager, run_telemetry: GenericEventBuilder, @@ -64,6 +64,7 @@ pub struct Run { task_access: TaskAccess, daemon: Option>, should_print_prelude: bool, + experimental_ui: bool, } impl Run { @@ -117,7 +118,41 @@ impl Run { new_run } - pub async fn run(&mut self) -> Result { + // Produces the transitive closure of the filtered packages, + // i.e. the packages relevant for this run. + pub fn get_relevant_packages(&self) -> HashSet { + let packages: Vec<_> = self + .filtered_pkgs + .iter() + .map(|pkg| PackageNode::Workspace(pkg.clone())) + .collect(); + self.pkg_dep_graph + .transitive_closure(&packages) + .into_iter() + .filter_map(|node| match node { + PackageNode::Root => None, + PackageNode::Workspace(pkg) => Some(pkg.clone()), + }) + .collect() + } + + pub fn has_experimental_ui(&self) -> bool { + self.experimental_ui + } + + pub fn start_experimental_ui(&self) -> Option<(AppSender, JoinHandle>)> { + if !self.experimental_ui { + return None; + } + + let task_names = self.engine.tasks_with_command(&self.pkg_dep_graph); + let (sender, receiver) = AppSender::new(); + let handle = tokio::task::spawn_blocking(move || tui::run_app(task_names, receiver)); + + Some((sender, handle)) + } + + pub async fn run(&mut self, experimental_ui_sender: Option) -> Result { if self.should_print_prelude { self.print_run_prelude(); } @@ -240,7 +275,7 @@ impl Run { self.processes.clone(), &self.repo_root, global_env, - self.experimental_ui, + experimental_ui_sender, ); if self.opts.run_opts.dry_run.is_some() { @@ -279,6 +314,7 @@ impl Run { &self.engine, &self.env_at_execution_start, self.opts.scope_opts.pkg_inference_root.as_deref(), + self.experimental_ui, ) .await?; diff --git a/crates/turborepo-lib/src/run/summary/mod.rs b/crates/turborepo-lib/src/run/summary/mod.rs index 0da5b5f7fa055..4def93fa02742 100644 --- a/crates/turborepo-lib/src/run/summary/mod.rs +++ b/crates/turborepo-lib/src/run/summary/mod.rs @@ -278,6 +278,7 @@ impl RunTracker { engine: &'a Engine, hash_tracker: TaskHashTracker, env_at_execution_start: &'a EnvironmentVariableMap, + has_experimental_ui: bool, ) -> Result<(), Error> { let end_time = Local::now(); @@ -305,7 +306,7 @@ impl RunTracker { .await?; run_summary - .finish(end_time, exit_code, pkg_dep_graph, ui) + .finish(end_time, exit_code, pkg_dep_graph, ui, has_experimental_ui) .await } @@ -380,6 +381,7 @@ impl<'a> RunSummary<'a> { exit_code: i32, pkg_dep_graph: &PackageGraph, ui: UI, + has_experimental_ui: bool, ) -> Result<(), Error> { if matches!(self.run_type, RunType::DryJson | RunType::DryText) { return self.close_dry_run(pkg_dep_graph, ui); @@ -391,10 +393,12 @@ impl<'a> RunSummary<'a> { } } - if let Some(execution) = &self.execution { - let path = self.get_path(); - let failed_tasks = self.get_failed_tasks(); - execution.print(ui, path, failed_tasks); + if !has_experimental_ui { + if let Some(execution) = &self.execution { + let path = self.get_path(); + let failed_tasks = self.get_failed_tasks(); + execution.print(ui, path, failed_tasks); + } } if let Some(spaces_client_handle) = self.spaces_client_handle.take() { diff --git a/crates/turborepo-lib/src/run/summary/spaces.rs b/crates/turborepo-lib/src/run/summary/spaces.rs index 5d909ac5385ac..e35d8c1bc0a05 100644 --- a/crates/turborepo-lib/src/run/summary/spaces.rs +++ b/crates/turborepo-lib/src/run/summary/spaces.rs @@ -351,6 +351,8 @@ fn trim_logs(logs: &[u8], limit: usize) -> String { #[cfg(test)] mod tests { + use std::time::Duration; + use anyhow::Result; use chrono::Local; use pretty_assertions::assert_eq; @@ -375,7 +377,13 @@ mod tests { let port = port_scanner::request_open_port().unwrap(); let handle = tokio::spawn(start_test_server(port)); - let api_client = APIClient::new(format!("http://localhost:{}", port), 2, "", true)?; + let api_client = APIClient::new( + format!("http://localhost:{}", port), + Some(Duration::from_secs(2)), + None, + "", + true, + )?; let api_auth = Some(APIAuth { token: EXPECTED_TOKEN.to_string(), diff --git a/crates/turborepo-lib/src/run/watch.rs b/crates/turborepo-lib/src/run/watch.rs index d172e39ff78ab..bd78429141026 100644 --- a/crates/turborepo-lib/src/run/watch.rs +++ b/crates/turborepo-lib/src/run/watch.rs @@ -1,11 +1,16 @@ -use std::collections::HashMap; +use std::{cell::RefCell, collections::HashSet, sync::Arc}; use futures::StreamExt; use miette::{Diagnostic, SourceSpan}; use thiserror::Error; -use tokio::{select, task::JoinHandle}; +use tokio::{ + select, + sync::{Mutex, Notify}, + task::JoinHandle, +}; use turborepo_repository::package_graph::PackageName; use turborepo_telemetry::events::command::CommandEventBuilder; +use turborepo_ui::{tui, tui::AppSender}; use crate::{ cli::{Command, RunArgs}, @@ -18,7 +23,38 @@ use crate::{ DaemonConnector, DaemonPaths, }; -pub struct WatchClient {} +#[derive(Debug)] +enum ChangedPackages { + All, + Some(HashSet), +} + +impl Default for ChangedPackages { + fn default() -> Self { + ChangedPackages::Some(HashSet::new()) + } +} + +impl ChangedPackages { + pub fn is_empty(&self) -> bool { + match self { + ChangedPackages::All => false, + ChangedPackages::Some(pkgs) => pkgs.is_empty(), + } + } +} + +pub struct WatchClient { + run: Run, + watched_packages: HashSet, + persistent_tasks_handle: Option>>, + connector: DaemonConnector, + base: CommandBase, + telemetry: CommandEventBuilder, + handler: SignalHandler, + ui_sender: Option, + ui_handle: Option>>, +} #[derive(Debug, Error, Diagnostic)] pub enum Error { @@ -51,20 +87,20 @@ pub enum Error { }, #[error("daemon connection closed")] ConnectionClosed, + #[error("failed to subscribe to signal handler, shutting down")] + NoSignalHandler, #[error("watch interrupted due to signal")] SignalInterrupt, #[error("package change error")] PackageChange(#[from] tonic::Status), + #[error("could not connect to UI thread")] + UISend(String), } impl WatchClient { - pub async fn start(base: CommandBase, telemetry: CommandEventBuilder) -> Result<(), Error> { + pub async fn new(base: CommandBase, telemetry: CommandEventBuilder) -> Result { let signal = commands::run::get_signal()?; let handler = SignalHandler::new(signal); - let Some(signal_subscriber) = handler.subscribe() else { - tracing::warn!("failed to subscribe to signal handler, shutting down"); - return Ok(()); - }; let Some(Command::Watch(execution_args)) = &base.args().command else { unreachable!() @@ -76,11 +112,13 @@ impl WatchClient { execution_args: execution_args.clone(), }); - let mut run = RunBuilder::new(new_base)? + let run = RunBuilder::new(new_base)? .build(&handler, telemetry.clone()) .await?; - run.print_run_prelude(); + let watched_packages = run.get_relevant_packages(); + + let (sender, handle) = run.start_experimental_ui().unzip(); let connector = DaemonConnector { can_start_server: true, @@ -88,31 +126,59 @@ impl WatchClient { paths: DaemonPaths::from_repo_root(&base.repo_root), }; + Ok(Self { + base, + run, + watched_packages, + connector, + handler, + telemetry, + persistent_tasks_handle: None, + ui_sender: sender, + ui_handle: handle, + }) + } + + pub async fn start(&mut self) -> Result<(), Error> { + let connector = self.connector.clone(); let mut client = connector.connect().await?; let mut events = client.package_changes().await?; - let mut current_runs: HashMap>> = - HashMap::new(); - let mut persistent_tasks_handle = None; + + if !self.run.has_experimental_ui() { + self.run.print_run_prelude(); + } + + let signal_subscriber = self.handler.subscribe().ok_or(Error::NoSignalHandler)?; + + // We explicitly use a tokio::sync::Mutex here to avoid deadlocks. + // If we used a std::sync::Mutex, we could deadlock by spinning the lock + // and not yielding back to the tokio runtime. + let changed_packages = Mutex::new(RefCell::new(ChangedPackages::default())); + let notify_run = Arc::new(Notify::new()); + let notify_event = notify_run.clone(); let event_fut = async { while let Some(event) = events.next().await { let event = event?; - Self::handle_change_event( - &mut run, - event.event.unwrap(), - &mut current_runs, - &base, - &telemetry, - &handler, - &mut persistent_tasks_handle, - ) - .await?; + Self::handle_change_event(&changed_packages, event.event.unwrap()).await?; + notify_event.notify_one(); } Err(Error::ConnectionClosed) }; + let run_fut = async { + loop { + notify_run.notified().await; + let changed_packages_guard = changed_packages.lock().await; + if !changed_packages_guard.borrow().is_empty() { + let changed_packages = changed_packages_guard.take(); + self.execute_run(changed_packages).await?; + } + } + }; + select! { biased; _ = signal_subscriber.listen() => { @@ -123,17 +189,15 @@ impl WatchClient { result = event_fut => { result } + run_result = run_fut => { + run_result + } } } async fn handle_change_event( - run: &mut Run, + changed_packages: &Mutex>, event: proto::package_change_event::Event, - current_runs: &mut HashMap>>, - base: &CommandBase, - telemetry: &CommandEventBuilder, - handler: &SignalHandler, - persistent_tasks_handle: &mut Option>>, ) -> Result<(), Error> { // Should we recover here? match event { @@ -141,12 +205,40 @@ impl WatchClient { package_name, }) => { let package_name = PackageName::from(package_name); - // If not in the filtered pkgs, ignore - if !run.filtered_pkgs.contains(&package_name) { - return Ok(()); + + match changed_packages.lock().await.get_mut() { + ChangedPackages::All => { + // If we've already changed all packages, ignore + } + ChangedPackages::Some(ref mut pkgs) => { + pkgs.insert(package_name); + } } + } + proto::package_change_event::Event::RediscoverPackages(_) => { + *changed_packages.lock().await.get_mut() = ChangedPackages::All; + } + proto::package_change_event::Event::Error(proto::PackageChangeError { message }) => { + return Err(DaemonError::Unavailable(message).into()); + } + } + + Ok(()) + } + + async fn execute_run(&mut self, changed_packages: ChangedPackages) -> Result { + // Should we recover here? + match changed_packages { + ChangedPackages::Some(packages) => { + let packages = packages + .into_iter() + .filter(|pkg| { + // If not in the watched packages set, ignore + self.watched_packages.contains(pkg) + }) + .collect(); - let mut args = base.args().clone(); + let mut args = self.base.args().clone(); args.command = args.command.map(|c| { if let Command::Watch(execution_args) = c { Command::Run { @@ -162,32 +254,26 @@ impl WatchClient { } }); - let new_base = - CommandBase::new(args, base.repo_root.clone(), get_version(), base.ui); - - // TODO: Add logic on when to abort vs wait - if let Some(run) = current_runs.remove(&package_name) { - run.abort(); - } + let new_base = CommandBase::new( + args, + self.base.repo_root.clone(), + get_version(), + self.base.ui, + ); - let signal_handler = handler.clone(); - let telemetry = telemetry.clone(); + let signal_handler = self.handler.clone(); + let telemetry = self.telemetry.clone(); - current_runs.insert( - package_name.clone(), - tokio::spawn(async move { - let mut run = RunBuilder::new(new_base)? - .with_entrypoint_package(package_name) - .hide_prelude() - .build(&signal_handler, telemetry) - .await?; + let mut run = RunBuilder::new(new_base)? + .with_entrypoint_packages(packages) + .hide_prelude() + .build(&signal_handler, telemetry) + .await?; - run.run().await - }), - ); + Ok(run.run(self.ui_sender.clone()).await?) } - proto::package_change_event::Event::RediscoverPackages(_) => { - let mut args = base.args().clone(); + ChangedPackages::All => { + let mut args = self.base.args().clone(); args.command = args.command.map(|c| { if let Command::Watch(execution_args) = c { Command::Run { @@ -203,43 +289,50 @@ impl WatchClient { } }); - let base = CommandBase::new(args, base.repo_root.clone(), get_version(), base.ui); - - // When we rediscover, stop all current runs - for (_, run) in current_runs.drain() { - run.abort(); - } + let base = CommandBase::new( + args, + self.base.repo_root.clone(), + get_version(), + self.base.ui, + ); // rebuild run struct - *run = RunBuilder::new(base.clone())? + self.run = RunBuilder::new(base.clone())? .hide_prelude() - .build(handler, telemetry.clone()) + .build(&self.handler, self.telemetry.clone()) .await?; - if run.has_persistent_tasks() { + self.watched_packages = self.run.get_relevant_packages(); + + if let Some(sender) = &self.ui_sender { + let task_names = self.run.engine.tasks_with_command(&self.run.pkg_dep_graph); + sender + .update_tasks(task_names) + .map_err(|err| Error::UISend(err.to_string()))?; + } + + if self.run.has_persistent_tasks() { // Abort old run - if let Some(run) = persistent_tasks_handle.take() { + if let Some(run) = self.persistent_tasks_handle.take() { run.abort(); } - let mut persistent_run = run.create_run_for_persistent_tasks(); + let mut persistent_run = self.run.create_run_for_persistent_tasks(); + let ui_sender = self.ui_sender.clone(); // If we have persistent tasks, we run them on a separate thread // since persistent tasks don't finish - *persistent_tasks_handle = - Some(tokio::spawn(async move { persistent_run.run().await })); + self.persistent_tasks_handle = + Some(tokio::spawn( + async move { persistent_run.run(ui_sender).await }, + )); // But we still run the regular tasks blocking - let mut non_persistent_run = run.create_run_without_persistent_tasks(); - non_persistent_run.run().await?; + let mut non_persistent_run = self.run.create_run_without_persistent_tasks(); + Ok(non_persistent_run.run(self.ui_sender.clone()).await?) } else { - run.run().await?; + Ok(self.run.run(self.ui_sender.clone()).await?) } } - proto::package_change_event::Event::Error(proto::PackageChangeError { message }) => { - return Err(DaemonError::Unavailable(message).into()); - } } - - Ok(()) } } diff --git a/crates/turborepo-lib/src/task_graph/visitor.rs b/crates/turborepo-lib/src/task_graph/visitor.rs index fcac062b9bca6..64b2b0937a145 100644 --- a/crates/turborepo-lib/src/task_graph/visitor.rs +++ b/crates/turborepo-lib/src/task_graph/visitor.rs @@ -9,6 +9,7 @@ use std::{ use console::{Style, StyledObject}; use either::Either; use futures::{stream::FuturesUnordered, StreamExt}; +use itertools::Itertools; use regex::Regex; use tokio::sync::{mpsc, oneshot}; use tracing::{debug, error, Instrument, Span}; @@ -23,7 +24,7 @@ use turborepo_telemetry::events::{ generic::GenericEventBuilder, task::PackageTaskEventBuilder, EventBuilder, TrackedErrors, }; use turborepo_ui::{ - tui::{self, TuiTask}, + tui::{self, AppSender, TuiTask}, ColorSelector, OutputClient, OutputSink, OutputWriter, PrefixedUI, UI, }; use which::which; @@ -41,7 +42,7 @@ use crate::{ }, task_access::TaskAccess, task_id::TaskId, - RunCache, TaskCache, + CacheOutput, RunCache, TaskCache, }, task_hash::{self, PackageInputsHashes, TaskHashTracker, TaskHashTrackerState, TaskHasher}, }; @@ -62,7 +63,7 @@ pub struct Visitor<'a> { sink: OutputSink, task_hasher: TaskHasher<'a>, ui: UI, - experimental_ui: bool, + experimental_ui_sender: Option, } #[derive(Debug, thiserror::Error)] @@ -84,6 +85,8 @@ pub enum Error { TaskHash(#[from] task_hash::Error), #[error(transparent)] RunSummary(#[from] summary::Error), + #[error("internal errors encountered: {0}")] + InternalErrors(String), } impl<'a> Visitor<'a> { @@ -105,7 +108,7 @@ impl<'a> Visitor<'a> { manager: ProcessManager, repo_root: &'a AbsoluteSystemPath, global_env: EnvironmentVariableMap, - experimental_ui: bool, + experimental_ui_sender: Option, ) -> Self { let task_hasher = TaskHasher::new( package_inputs_hashes, @@ -132,7 +135,7 @@ impl<'a> Visitor<'a> { task_hasher, ui, global_env, - experimental_ui, + experimental_ui_sender, } } @@ -145,16 +148,6 @@ impl<'a> Visitor<'a> { let concurrency = self.run_opts.concurrency as usize; let (node_sender, mut node_stream) = mpsc::channel(concurrency); - let (ui, render_thread_handle) = if self.experimental_ui { - let task_names = engine.tasks_with_command(&self.package_graph); - - let (handle, receiver) = tui::AppSender::new(); - let app = tokio::task::spawn_blocking(move || tui::run_app(task_names, receiver)); - (Some(handle), Some(app)) - } else { - (None, None) - }; - let engine_handle = { let engine = engine.clone(); tokio::spawn(engine.execute(ExecutionOptions::new(false, concurrency), node_sender)) @@ -253,7 +246,7 @@ impl<'a> Visitor<'a> { factory.dry_run_exec_context(info.clone(), task_cache); let tracker = self.run_tracker.track_task(info.into_owned()); tasks.push(tokio::spawn(async move { - dry_run_exec_context.execute_dry_run(tracker).await; + dry_run_exec_context.execute_dry_run(tracker).await })); } false => { @@ -282,7 +275,7 @@ impl<'a> Visitor<'a> { let vendor_behavior = Vendor::infer().and_then(|vendor| vendor.behavior.as_ref()); - let output_client = if let Some(handle) = &ui { + let output_client = if let Some(handle) = &self.experimental_ui_sender { TaskOutput::UI(handle.task(info.to_string())) } else { TaskOutput::Direct(self.output_client(&info, vendor_behavior)) @@ -302,7 +295,7 @@ impl<'a> Visitor<'a> { spaces_client, &execution_telemetry, ) - .await; + .await })); } } @@ -311,19 +304,18 @@ impl<'a> Visitor<'a> { // Wait for the engine task to finish and for all of our tasks to finish engine_handle.await.expect("engine execution panicked")?; // This will poll the futures until they are all completed + let mut internal_errors = Vec::new(); while let Some(result) = tasks.next().await { - result.unwrap_or_else(|e| panic!("task executor panicked: {e}")); + if let Err(e) = result.unwrap_or_else(|e| panic!("task executor panicked: {e}")) { + internal_errors.push(e); + } } drop(factory); - if let Some(handle) = ui { - handle.stop(); - if let Err(e) = render_thread_handle - .unwrap() - .await - .expect("render thread panicked") - { - error!("error encountered rendering tui: {e}"); - } + + if !internal_errors.is_empty() { + return Err(Error::InternalErrors( + internal_errors.into_iter().map(|e| e.to_string()).join(","), + )); } // Write out the traced-config.json file if we have one @@ -339,6 +331,8 @@ impl<'a> Visitor<'a> { /// Finishes visiting the tasks, creates the run summary, and either /// prints, saves, or sends it to spaces. + + #[allow(clippy::too_many_arguments)] #[tracing::instrument(skip( self, packages, @@ -354,6 +348,7 @@ impl<'a> Visitor<'a> { engine: &Engine, env_at_execution_start: &EnvironmentVariableMap, pkg_inference_root: Option<&AnchoredSystemPath>, + has_experimental_ui: bool, ) -> Result<(), Error> { let Self { package_graph, @@ -382,6 +377,7 @@ impl<'a> Visitor<'a> { engine, task_hasher.task_hash_tracker(), env_at_execution_start, + has_experimental_ui, ) .await?) } @@ -483,7 +479,7 @@ impl<'a> Visitor<'a> { pub fn dry_run(&mut self) { self.dry = true; // No need to start a TUI on dry run - self.experimental_ui = false; + self.experimental_ui_sender = None; } } @@ -560,6 +556,22 @@ enum TaskErrorCause { Spawn { msg: String }, #[error("command {command} exited ({exit_code})")] Exit { command: String, exit_code: i32 }, + #[error("turbo has internal error processing task")] + Internal, +} + +#[derive(Debug, thiserror::Error)] +pub enum InternalError { + #[error(transparent)] + Io(#[from] std::io::Error), + #[error("unable to determine why task exited")] + UnknownChildExit, + #[error("unable to find package manager binary: {0}")] + Which(#[from] which::Error), + #[error("external process killed a task")] + ExternalKill, + #[error("error writing logs: {0}")] + Logs(#[from] crate::run::CacheError), } impl TaskError { @@ -637,7 +649,7 @@ impl<'a> ExecContextFactory<'a> { ExecContext { engine: self.engine.clone(), ui: self.visitor.ui, - experimental_ui: self.visitor.experimental_ui, + experimental_ui: self.visitor.experimental_ui_sender.is_some(), is_github_actions: self.visitor.run_opts.is_github_actions, pretty_prefix: self .visitor @@ -698,13 +710,13 @@ struct ExecContext { enum ExecOutcome { // All operations during execution succeeded Success(SuccessOutcome), - // An internal error that indicates a shutdown should be performed - Internal, // An error with the task execution Task { exit_code: Option, message: String, }, + // Task didn't execute normally due to a shutdown being initiated by another task + Shutdown, } enum SuccessOutcome { @@ -729,7 +741,7 @@ impl ExecContext { callback: oneshot::Sender>, spaces_client: Option, telemetry: &PackageTaskEventBuilder, - ) { + ) -> Result<(), InternalError> { let tracker = tracker.start().await; let span = tracing::debug_span!("execute_task", task = %self.task_id.task()); span.follows_from(parent_span_id); @@ -740,19 +752,19 @@ impl ExecContext { // If the task resulted in an error, do not group in order to better highlight // the error. - let is_error = matches!(result, ExecOutcome::Task { .. }); + let is_error = matches!(result, Ok(ExecOutcome::Task { .. })); let logs = match output_client.finish(is_error) { Ok(logs) => logs, Err(e) => { telemetry.track_error(TrackedErrors::DaemonFailedToMarkOutputsAsCached); error!("unable to flush output client: {e}"); - result = ExecOutcome::Internal; + result = Err(InternalError::Io(e)); None } }; match result { - ExecOutcome::Success(outcome) => { + Ok(ExecOutcome::Success(outcome)) => { let task_summary = match outcome { SuccessOutcome::CacheHit => tracker.cached().await, SuccessOutcome::Run => tracker.build_succeeded(0).await, @@ -764,12 +776,7 @@ impl ExecContext { client.finish_task(info).await.ok(); } } - ExecOutcome::Internal => { - tracker.cancel(); - callback.send(Err(StopExecution)).ok(); - self.manager.stop().await; - } - ExecOutcome::Task { exit_code, message } => { + Ok(ExecOutcome::Task { exit_code, message }) => { let task_summary = tracker.build_failed(exit_code, message).await; callback .send(match self.continue_on_error { @@ -800,26 +807,47 @@ impl ExecContext { } } } + Ok(ExecOutcome::Shutdown) => { + tracker.cancel(); + callback.send(Err(StopExecution)).ok(); + // Probably overkill here, but we should make sure the process manager is + // stopped if we think we're shutting down. + self.manager.stop().await; + } + Err(e) => { + tracker.cancel(); + callback.send(Err(StopExecution)).ok(); + self.manager.stop().await; + return Err(e); + } } + + Ok(()) } - fn prefixed_ui(&self, stdout: W, stderr: W) -> PrefixedUI { - Visitor::prefixed_ui( - self.ui, - self.is_github_actions, - stdout, - stderr, - self.pretty_prefix.clone(), - ) + fn prefixed_ui<'a, W: Write>( + &self, + output_client: &'a TaskOutput, + ) -> TaskCacheOutput> { + match output_client { + TaskOutput::Direct(client) => TaskCacheOutput::Direct(Visitor::prefixed_ui( + self.ui, + self.is_github_actions, + client.stdout(), + client.stderr(), + self.pretty_prefix.clone(), + )), + TaskOutput::UI(task) => TaskCacheOutput::UI(task.clone()), + } } async fn execute_inner( &mut self, output_client: &TaskOutput, telemetry: &PackageTaskEventBuilder, - ) -> ExecOutcome { + ) -> Result { let task_start = Instant::now(); - let mut prefixed_ui = self.prefixed_ui(output_client.stdout(), output_client.stderr()); + let mut prefixed_ui = self.prefixed_ui(output_client); if self.experimental_ui { if let TaskOutput::UI(task) = output_client { @@ -827,19 +855,9 @@ impl ExecContext { } } - // When the UI is enabled we don't want to have the prefix appear on the - // replayed logs. - let alt_log_replay_writer = match output_client { - TaskOutput::UI(task) => Some(task.clone()), - TaskOutput::Direct(_) => None, - }; match self .task_cache - .restore_outputs( - prefixed_ui.output_prefixed_writer(), - alt_log_replay_writer, - telemetry, - ) + .restore_outputs(&mut prefixed_ui, telemetry) .await { Ok(Some(status)) => { @@ -850,18 +868,16 @@ impl ExecContext { ); self.hash_tracker .insert_cache_status(self.task_id.clone(), status); - return ExecOutcome::Success(SuccessOutcome::CacheHit); + return Ok(ExecOutcome::Success(SuccessOutcome::CacheHit)); } Ok(None) => (), Err(e) => { telemetry.track_error(TrackedErrors::ErrorFetchingFromCache); - prefixed_ui.error(format!("error fetching from cache: {e}")); + prefixed_ui.error(&format!("error fetching from cache: {e}")); } } - let Ok(package_manager_binary) = which(self.package_manager.command()) else { - return ExecOutcome::Internal; - }; + let package_manager_binary = which(self.package_manager.command())?; let mut cmd = Command::new(package_manager_binary); let mut args = vec!["run".to_string(), self.task_id.task().to_string()]; @@ -897,20 +913,20 @@ impl ExecContext { // Turbo was unable to spawn a process Some(Err(e)) => { // Note: we actually failed to spawn, but this matches the Go output - prefixed_ui.error(format!("command finished with error: {e}")); + prefixed_ui.error(&format!("command finished with error: {e}")); let error_string = e.to_string(); self.errors .lock() .expect("lock poisoned") .push(TaskError::from_spawn(self.task_id_for_display.clone(), e)); - return ExecOutcome::Task { + return Ok(ExecOutcome::Task { exit_code: None, message: error_string, - }; + }); } // Turbo is shutting down None => { - return ExecOutcome::Internal; + return Ok(ExecOutcome::Shutdown); } }; @@ -922,25 +938,19 @@ impl ExecContext { } } - let mut stdout_writer = match self.task_cache.output_writer(if self.experimental_ui { - Either::Left(output_client.stdout()) - } else { - Either::Right(prefixed_ui.output_prefixed_writer()) - }) { - Ok(w) => w, - Err(e) => { + let mut stdout_writer = self + .task_cache + .output_writer(prefixed_ui.task_writer()) + .map_err(|e| { telemetry.track_error(TrackedErrors::FailedToCaptureOutputs); - error!("failed to capture outputs for \"{}\": {e}", self.task_id); - return ExecOutcome::Internal; - } - }; + e + })?; let exit_status = match process.wait_with_piped_outputs(&mut stdout_writer).await { Ok(Some(exit_status)) => exit_status, Err(e) => { telemetry.track_error(TrackedErrors::FailedToPipeOutputs); - error!("unable to pipe outputs from command: {e}"); - return ExecOutcome::Internal; + return Err(e.into()); } Ok(None) => { // TODO: how can this happen? we only update the @@ -948,7 +958,7 @@ impl ExecContext { // None. Is it still running? telemetry.track_error(TrackedErrors::UnknownChildExit); error!("unable to determine why child exited"); - return ExecOutcome::Internal; + return Err(InternalError::UnknownChildExit); } }; let task_duration = task_start.elapsed(); @@ -965,6 +975,7 @@ impl ExecContext { { if let Err(e) = self.task_cache.save_outputs(task_duration, telemetry).await { error!("error caching output: {e}"); + return Err(e.into()); } else { // If no errors, update hash tracker with expanded outputs self.hash_tracker.insert_expanded_outputs( @@ -975,17 +986,14 @@ impl ExecContext { } // Return success outcome - ExecOutcome::Success(SuccessOutcome::Run) + Ok(ExecOutcome::Success(SuccessOutcome::Run)) } ChildExit::Finished(Some(code)) => { // If there was an error, flush the buffered output if let Err(e) = stdout_writer.flush() { error!("error flushing logs: {e}"); } - if let Err(e) = self - .task_cache - .on_error(prefixed_ui.output_prefixed_writer()) - { + if let Err(e) = self.task_cache.on_error(&mut prefixed_ui) { error!("error reading logs: {e}"); } let error = TaskErrorCause::from_execution(process.label().to_string(), code); @@ -993,22 +1001,24 @@ impl ExecContext { if self.continue_on_error { prefixed_ui.warn("command finished with error, but continuing..."); } else { - prefixed_ui.error(format!("command finished with error: {error}")); + prefixed_ui.error(&format!("command finished with error: {error}")); } self.errors.lock().expect("lock poisoned").push(TaskError { task_id: self.task_id_for_display.clone(), cause: error, }); - ExecOutcome::Task { + Ok(ExecOutcome::Task { exit_code: Some(code), message, - } + }) } - // All of these indicate a failure where we don't know how to recover - ChildExit::Finished(None) - | ChildExit::Killed - | ChildExit::KilledExternal - | ChildExit::Failed => ExecOutcome::Internal, + // The child exited in a way where we can't figure out how it finished so we assume it + // failed. + ChildExit::Finished(None) | ChildExit::Failed => Err(InternalError::UnknownChildExit), + // Something else killed the child + ChildExit::KilledExternal => Err(InternalError::ExternalKill), + // The child was killed by turbo indicating a shutdown + ChildExit::Killed => Ok(ExecOutcome::Shutdown), } } @@ -1040,21 +1050,76 @@ struct DryRunExecContext { } impl DryRunExecContext { - pub async fn execute_dry_run(&self, tracker: TaskTracker<()>) { + pub async fn execute_dry_run(&self, tracker: TaskTracker<()>) -> Result<(), InternalError> { // may also need to do framework & command stuff? if let Ok(Some(status)) = self.task_cache.exists().await { self.hash_tracker .insert_cache_status(self.task_id.clone(), status); } tracker.dry_run().await; + Ok(()) + } +} + +/// Struct for displaying information about task's cache +enum TaskCacheOutput { + Direct(PrefixedUI), + UI(TuiTask), +} + +impl TaskCacheOutput { + fn task_writer(&mut self) -> Either, TuiTask> { + match self { + TaskCacheOutput::Direct(prefixed) => Either::Left(prefixed.output_prefixed_writer()), + TaskCacheOutput::UI(task) => Either::Right(task.clone()), + } + } + + fn warn(&mut self, message: impl std::fmt::Display) { + match self { + TaskCacheOutput::Direct(prefixed) => prefixed.warn(message), + TaskCacheOutput::UI(task) => { + let _ = write!(task, "\r\n{message}\r\n"); + } + } + } +} + +impl CacheOutput for TaskCacheOutput { + fn status(&mut self, message: &str) { + match self { + TaskCacheOutput::Direct(direct) => direct.output(message), + TaskCacheOutput::UI(task) => task.status(message), + } + } + + fn error(&mut self, message: &str) { + match self { + TaskCacheOutput::Direct(prefixed) => prefixed.error(message), + TaskCacheOutput::UI(task) => { + let _ = write!(task, "{message}\r\n"); + } + } + } + + fn replay_logs(&mut self, log_file: &AbsoluteSystemPath) -> Result<(), turborepo_ui::Error> { + match self { + TaskCacheOutput::Direct(direct) => { + let writer = direct.output_prefixed_writer(); + turborepo_ui::replay_logs(writer, log_file) + } + TaskCacheOutput::UI(task) => turborepo_ui::replay_logs(task, log_file), + } } } +/// Struct for displaying information about task impl TaskOutput { pub fn finish(self, use_error: bool) -> std::io::Result>> { match self { TaskOutput::Direct(client) => client.finish(use_error), - TaskOutput::UI(client) => Ok(Some(client.finish())), + TaskOutput::UI(client) if use_error => Ok(Some(client.failed())), + TaskOutput::UI(client) => Ok(Some(client.succeeded())), } } diff --git a/crates/turborepo-lockfiles/src/berry/mod.rs b/crates/turborepo-lockfiles/src/berry/mod.rs index 3713bf5c0d936..c6417a22a3157 100644 --- a/crates/turborepo-lockfiles/src/berry/mod.rs +++ b/crates/turborepo-lockfiles/src/berry/mod.rs @@ -774,6 +774,7 @@ mod test { &lockfile, "apps/docs", HashMap::from_iter(vec![("lodash".into(), "^4.17.21".into())]), + false, ) .unwrap(); @@ -883,7 +884,7 @@ mod test { .map(|(k, v)| (k.to_string(), v.to_string())) .collect(); - let closure = transitive_closure(&lockfile, "packages/ui", unresolved_deps).unwrap(); + let closure = transitive_closure(&lockfile, "packages/ui", unresolved_deps, false).unwrap(); assert!(closure.contains(&Package { key: "ajv@npm:8.11.2".into(), @@ -1063,6 +1064,7 @@ mod test { )] .into_iter() .collect(), + false, ) .unwrap(); diff --git a/crates/turborepo-lockfiles/src/lib.rs b/crates/turborepo-lockfiles/src/lib.rs index e62d0b35e32ff..9434bc1b1a93c 100644 --- a/crates/turborepo-lockfiles/src/lib.rs +++ b/crates/turborepo-lockfiles/src/lib.rs @@ -69,11 +69,17 @@ pub trait Lockfile: Send + Sync + Any + std::fmt::Debug { pub fn all_transitive_closures( lockfile: &L, workspaces: HashMap>, + ignore_missing_packages: bool, ) -> Result>, Error> { workspaces .into_par_iter() .map(|(workspace, unresolved_deps)| { - let closure = transitive_closure(lockfile, &workspace, unresolved_deps)?; + let closure = transitive_closure( + lockfile, + &workspace, + unresolved_deps, + ignore_missing_packages, + )?; Ok((workspace, closure)) }) .collect() @@ -85,6 +91,7 @@ pub fn transitive_closure( lockfile: &L, workspace_path: &str, unresolved_deps: HashMap, + ignore_missing_packages: bool, ) -> Result, Error> { let mut transitive_deps = HashSet::new(); transitive_closure_helper( @@ -92,6 +99,7 @@ pub fn transitive_closure( workspace_path, unresolved_deps, &mut transitive_deps, + ignore_missing_packages, )?; Ok(transitive_deps) @@ -102,9 +110,16 @@ fn transitive_closure_helper( workspace_path: &str, unresolved_deps: HashMap>, resolved_deps: &mut HashSet, + ignore_missing_packages: bool, ) -> Result<(), Error> { for (name, specifier) in unresolved_deps { - let pkg = lockfile.resolve_package(workspace_path, &name, specifier.as_ref())?; + let pkg = match lockfile.resolve_package(workspace_path, &name, specifier.as_ref()) { + Ok(pkg) => pkg, + Err(Error::MissingWorkspace(_)) if ignore_missing_packages => { + continue; + } + Err(e) => return Err(e), + }; match pkg { None => { @@ -117,7 +132,15 @@ fn transitive_closure_helper( let all_deps = lockfile.all_dependencies(&pkg.key)?; resolved_deps.insert(pkg); if let Some(deps) = all_deps { - transitive_closure_helper(lockfile, workspace_path, deps, resolved_deps)?; + // we've already found one unresolved dependency, so we can't ignore its set of + // dependencies. + transitive_closure_helper( + lockfile, + workspace_path, + deps, + resolved_deps, + false, + )?; } } } diff --git a/crates/turborepo-lockfiles/src/npm.rs b/crates/turborepo-lockfiles/src/npm.rs index bc7f2f7daecef..191550f608135 100644 --- a/crates/turborepo-lockfiles/src/npm.rs +++ b/crates/turborepo-lockfiles/src/npm.rs @@ -440,6 +440,7 @@ mod test { ] .into_iter() .collect(), + false, )?; assert!(closures.get("packages/a").unwrap().contains(&Package { key: "node_modules/eslint-plugin-turbo".into(), diff --git a/crates/turborepo-lockfiles/src/pnpm/data.rs b/crates/turborepo-lockfiles/src/pnpm/data.rs index 9ff2cfd07184f..ea028cf0eabe0 100644 --- a/crates/turborepo-lockfiles/src/pnpm/data.rs +++ b/crates/turborepo-lockfiles/src/pnpm/data.rs @@ -966,6 +966,7 @@ mod tests { )] .into_iter() .collect(), + false, ) .unwrap(); @@ -1037,6 +1038,7 @@ c: )] .into_iter() .collect(), + false, ) .unwrap(); @@ -1113,7 +1115,7 @@ c: .map(|(k, v)| (k.to_owned(), v.to_owned())) .collect(), ); - let mut closures: Vec<_> = crate::all_transitive_closures(&lockfile, workspaces) + let mut closures: Vec<_> = crate::all_transitive_closures(&lockfile, workspaces, false) .unwrap() .into_iter() .map(|(k, v)| (k, v.into_iter().sorted().collect::>())) diff --git a/crates/turborepo-paths/src/anchored_system_path.rs b/crates/turborepo-paths/src/anchored_system_path.rs index 31cd3b855d906..f0d6863963e44 100644 --- a/crates/turborepo-paths/src/anchored_system_path.rs +++ b/crates/turborepo-paths/src/anchored_system_path.rs @@ -152,6 +152,15 @@ impl AnchoredSystemPath { } } } + + // Note that this defers to Path::strip_prefix, which operates on components, + // and therefore enforces boundaries at path dividers. + pub fn strip_prefix(&self, other: &Self) -> Option { + self.0 + .strip_prefix(&other.0) + .ok() + .map(|path| AnchoredSystemPathBuf(path.to_owned())) + } } #[cfg(test)] diff --git a/crates/turborepo-repository/src/package_graph/builder.rs b/crates/turborepo-repository/src/package_graph/builder.rs index d4a3ea7ac3f32..1bf6caa82cbd4 100644 --- a/crates/turborepo-repository/src/package_graph/builder.rs +++ b/crates/turborepo-repository/src/package_graph/builder.rs @@ -507,9 +507,12 @@ impl<'a, T: PackageDiscovery> BuildState<'a, ResolvedLockfile, T> { return Ok(()); }; + // We cannot ignore missing packages in this context, it would indicate a + // malformed or stale lockfile. let mut closures = turborepo_lockfiles::all_transitive_closures( lockfile, self.all_external_dependencies()?, + false, )?; for (_, entry) in self.workspaces.iter_mut() { entry.transitive_dependencies = closures.remove(&entry.unix_dir_str()?); diff --git a/crates/turborepo-repository/src/package_graph/mod.rs b/crates/turborepo-repository/src/package_graph/mod.rs index 674e03a5686a9..eb8a902adcf3e 100644 --- a/crates/turborepo-repository/src/package_graph/mod.rs +++ b/crates/turborepo-repository/src/package_graph/mod.rs @@ -345,7 +345,12 @@ impl PackageGraph { }) .collect::>>(); - let closures = turborepo_lockfiles::all_transitive_closures(previous, external_deps)?; + // We're comparing to a previous lockfile, it's possible that a package was + // added and thus won't exist in the previous lockfile. In that case, + // we're fine to ignore it. Assuming there is not a commit with a stale + // lockfile, the same commit should add the package, so it will get + // picked up as changed. + let closures = turborepo_lockfiles::all_transitive_closures(previous, external_deps, true)?; let global_change = current.global_change(previous); diff --git a/crates/turborepo-repository/src/package_manager/mod.rs b/crates/turborepo-repository/src/package_manager/mod.rs index 6a139165fe8ba..e8f0d95abe7ef 100644 --- a/crates/turborepo-repository/src/package_manager/mod.rs +++ b/crates/turborepo-repository/src/package_manager/mod.rs @@ -281,8 +281,9 @@ pub enum Error { MultiplePackageManagers { managers: Vec }, #[error(transparent)] Semver(#[from] node_semver::SemverError), - #[error(transparent)] - Which(#[from] which::Error), + #[error("{0}: {1}")] + // this will be something like "cannot find binary: " + Which(which::Error, String), #[error("invalid utf8: {0}")] Utf8Error(#[from] std::string::FromUtf8Error), #[error(transparent)] @@ -525,7 +526,8 @@ impl PackageManager { let lockfile_path = self.lockfile_path(root_path); let contents = match self { PackageManager::Bun => { - Command::new(which("bun")?) + let binary = "bun"; + Command::new(which(binary).map_err(|e| Error::Which(e, binary.to_string()))?) .arg(lockfile_path.to_string()) .current_dir(root_path.to_string()) .output()? diff --git a/crates/turborepo-repository/src/package_manager/yarn.rs b/crates/turborepo-repository/src/package_manager/yarn.rs index febedb7d68807..7105e65958b34 100644 --- a/crates/turborepo-repository/src/package_manager/yarn.rs +++ b/crates/turborepo-repository/src/package_manager/yarn.rs @@ -37,7 +37,8 @@ impl<'a> YarnDetector<'a> { return Ok(version.clone()); } - let yarn_binary = which("yarn")?; + let binary = "yarn"; + let yarn_binary = which(binary).map_err(|e| Error::Which(e, binary.to_string()))?; let output = Command::new(yarn_binary) .arg("--version") .current_dir(self.repo_root) diff --git a/crates/turborepo-scm/src/package_deps.rs b/crates/turborepo-scm/src/package_deps.rs index 3227c1fb19a23..cfcf5baf5fd87 100644 --- a/crates/turborepo-scm/src/package_deps.rs +++ b/crates/turborepo-scm/src/package_deps.rs @@ -9,7 +9,7 @@ use crate::{hash_object::hash_objects, Error, Git, SCM}; pub type GitHashes = HashMap; -const INPUT_INCLUDE_DEFAULT_FILES: &str = "$TURBO_DEFAULT$"; +pub const INPUT_INCLUDE_DEFAULT_FILES: &str = "$TURBO_DEFAULT$"; impl SCM { pub fn get_hashes_for_files( diff --git a/crates/turborepo-telemetry/Cargo.toml b/crates/turborepo-telemetry/Cargo.toml index ac256775e9184..ab81ee991ea7d 100644 --- a/crates/turborepo-telemetry/Cargo.toml +++ b/crates/turborepo-telemetry/Cargo.toml @@ -16,7 +16,6 @@ test-case = { workspace = true } turborepo-vercel-api-mock = { workspace = true } [dependencies] -async-trait = { workspace = true } chrono = { workspace = true, features = ["serde"] } config = { version = "0.13.4", default-features = false, features = ["json"] } futures = { workspace = true } diff --git a/crates/turborepo-telemetry/src/lib.rs b/crates/turborepo-telemetry/src/lib.rs index a0bfe1c99fe75..64633ea7f8d47 100644 --- a/crates/turborepo-telemetry/src/lib.rs +++ b/crates/turborepo-telemetry/src/lib.rs @@ -256,7 +256,6 @@ mod tests { time::Duration, }; - use async_trait::async_trait; use tokio::{ select, sync::{mpsc, mpsc::UnboundedReceiver}, @@ -281,7 +280,6 @@ mod tests { } } - #[async_trait] impl TelemetryClient for DummyClient { async fn record_telemetry( &self, diff --git a/crates/turborepo-ui/examples/table.rs b/crates/turborepo-ui/examples/table.rs index 63c2434d41705..e39c5272bf8dd 100644 --- a/crates/turborepo-ui/examples/table.rs +++ b/crates/turborepo-ui/examples/table.rs @@ -5,7 +5,7 @@ use crossterm::{ terminal::{disable_raw_mode, enable_raw_mode}, }; use ratatui::prelude::*; -use turborepo_ui::TaskTable; +use turborepo_ui::{tui::event::TaskResult, TaskTable}; enum Event { Tick(u64), @@ -61,7 +61,7 @@ fn run_app( table.tick(); } Event::Start(task) => table.start_task(task).unwrap(), - Event::Finish(task) => table.finish_task(task).unwrap(), + Event::Finish(task) => table.finish_task(task, TaskResult::Success).unwrap(), Event::Up => table.previous(), Event::Down => table.next(), Event::Stop => break, diff --git a/crates/turborepo-ui/src/tui/app.rs b/crates/turborepo-ui/src/tui/app.rs index 8b693a4569672..d0ab438cda9cc 100644 --- a/crates/turborepo-ui/src/tui/app.rs +++ b/crates/turborepo-ui/src/tui/app.rs @@ -6,13 +6,10 @@ use std::{ use ratatui::{ backend::{Backend, CrosstermBackend}, layout::{Constraint, Layout}, - widgets::Widget, Frame, Terminal, }; use tracing::debug; -use tui_term::widget::PseudoTerminal; -const DEFAULT_APP_HEIGHT: u16 = 60; const PANE_SIZE_RATIO: f32 = 3.0 / 4.0; const FRAMERATE: Duration = Duration::from_millis(3); @@ -80,6 +77,11 @@ impl App { pub fn term_size(&self) -> (u16, u16) { self.pane.term_size() } + + pub fn update_tasks(&mut self, tasks: Vec) { + self.table = TaskTable::new(tasks.clone()); + self.next(); + } } impl App { @@ -100,46 +102,46 @@ impl App { /// Handle the rendering of the `App` widget based on events received by /// `receiver` pub fn run_app(tasks: Vec, receiver: AppReceiver) -> Result<(), Error> { - let (mut terminal, app_height) = startup()?; + let mut terminal = startup()?; let size = terminal.size()?; - let pane_height = (f32::from(app_height) * PANE_SIZE_RATIO) as u16; - let app: App> = App::new(pane_height, size.width, tasks); + // Figure out pane width? + let task_width_hint = TaskTable::width_hint(tasks.iter().map(|s| s.as_str())); + // Want to maximize pane width + let ratio_pane_width = (f32::from(size.width) * PANE_SIZE_RATIO) as u16; + let full_task_width = size.width.saturating_sub(task_width_hint); - let result = run_app_inner(&mut terminal, app, receiver); + let mut app: App> = + App::new(size.height, full_task_width.max(ratio_pane_width), tasks); - cleanup(terminal)?; + let result = run_app_inner(&mut terminal, &mut app, receiver); + + cleanup(terminal, app)?; result } // Break out inner loop so we can use `?` without worrying about cleaning up the // terminal. -fn run_app_inner( +fn run_app_inner( terminal: &mut Terminal, - mut app: App>, + app: &mut App>, receiver: AppReceiver, ) -> Result<(), Error> { // Render initial state to paint the screen - terminal.draw(|f| view(&mut app, f))?; + terminal.draw(|f| view(app, f))?; let mut last_render = Instant::now(); - while let Some(event) = poll(app.interact, &receiver, last_render + FRAMERATE) { - if let Some(message) = update(terminal, &mut app, event)? { - persist_bytes(terminal, &message)?; - } + update(app, event)?; if app.done { break; } if FRAMERATE <= last_render.elapsed() { - terminal.draw(|f| view(&mut app, f))?; + terminal.draw(|f| view(app, f))?; last_render = Instant::now(); } } - let started_tasks = app.table.tasks_started().collect(); - app.pane.render_remaining(started_tasks, terminal)?; - Ok(()) } @@ -155,40 +157,46 @@ fn poll(interact: bool, receiver: &AppReceiver, deadline: Instant) -> Option io::Result<(Terminal>, u16)> { +fn startup() -> io::Result>> { crossterm::terminal::enable_raw_mode()?; let mut stdout = io::stdout(); - crossterm::execute!(stdout, crossterm::event::EnableMouseCapture)?; + crossterm::execute!( + stdout, + crossterm::event::EnableMouseCapture, + crossterm::terminal::EnterAlternateScreen + )?; let backend = CrosstermBackend::new(stdout); - // We need to reserve at least 1 line for writing persistent lines. - let height = DEFAULT_APP_HEIGHT.min(backend.size()?.height.saturating_sub(1)); - let mut terminal = Terminal::with_options( backend, ratatui::TerminalOptions { - viewport: ratatui::Viewport::Inline(height), + viewport: ratatui::Viewport::Fullscreen, }, )?; terminal.hide_cursor()?; - Ok((terminal, height)) + Ok(terminal) } /// Restores terminal to expected state -fn cleanup(mut terminal: Terminal) -> io::Result<()> { +fn cleanup( + mut terminal: Terminal, + mut app: App, +) -> io::Result<()> { terminal.clear()?; crossterm::execute!( terminal.backend_mut(), - crossterm::event::DisableMouseCapture + crossterm::event::DisableMouseCapture, + crossterm::terminal::LeaveAlternateScreen, )?; + let started_tasks = app.table.tasks_started().collect(); + app.pane.render_remaining(started_tasks)?; crossterm::terminal::disable_raw_mode()?; terminal.show_cursor()?; Ok(()) } -fn update( - terminal: &mut Terminal, +fn update( app: &mut App>, event: Event, ) -> Result>, Error> { @@ -199,18 +207,17 @@ fn update( Event::TaskOutput { task, output } => { app.pane.process_output(&task, &output)?; } + Event::Status { task, status } => { + app.pane.set_status(&task, status)?; + } Event::Stop => { app.done = true; } Event::Tick => { app.table.tick(); } - Event::Log { message } => { - return Ok(Some(message)); - } - Event::EndTask { task } => { - app.table.finish_task(&task)?; - app.pane.render_screen(&task, terminal)?; + Event::EndTask { task, result } => { + app.table.finish_task(&task, result)?; } Event::Up => { app.previous(); @@ -236,55 +243,18 @@ fn update( Event::SetStdin { task, stdin } => { app.pane.insert_stdin(&task, Some(stdin))?; } + Event::UpdateTasks { tasks } => { + app.update_tasks(tasks); + app.table.tick(); + } } Ok(None) } fn view(app: &mut App, f: &mut Frame) { - let (term_height, _) = app.term_size(); - let vertical = Layout::vertical([Constraint::Min(5), Constraint::Length(term_height)]); + let (_, width) = app.term_size(); + let vertical = Layout::horizontal([Constraint::Fill(1), Constraint::Length(width)]); let [table, pane] = vertical.areas(f.size()); app.table.stateful_render(f, table); f.render_widget(&app.pane, pane); } - -/// Write provided bytes to a section of the screen that won't get rewritten -fn persist_bytes(terminal: &mut Terminal, bytes: &[u8]) -> Result<(), Error> { - let size = terminal.size()?; - let mut parser = turborepo_vt100::Parser::new(size.height, size.width, 128); - parser.process(bytes); - let screen = parser.entire_screen(); - let (height, _) = screen.size(); - terminal.insert_before(height as u16, |buf| { - PseudoTerminal::new(&screen).render(buf.area, buf) - })?; - Ok(()) -} - -#[cfg(test)] -mod test { - use ratatui::{backend::TestBackend, buffer::Buffer}; - - use super::*; - - #[test] - fn test_persist_bytes() { - let mut term = Terminal::with_options( - TestBackend::new(10, 7), - ratatui::TerminalOptions { - viewport: ratatui::Viewport::Inline(3), - }, - ) - .unwrap(); - persist_bytes(&mut term, b"two\r\nlines").unwrap(); - term.backend().assert_buffer(&Buffer::with_lines(vec![ - "two ", - "lines ", - " ", - " ", - " ", - " ", - " ", - ])); - } -} diff --git a/crates/turborepo-ui/src/tui/event.rs b/crates/turborepo-ui/src/tui/event.rs index 97034644d5621..a5942d33ef904 100644 --- a/crates/turborepo-ui/src/tui/event.rs +++ b/crates/turborepo-ui/src/tui/event.rs @@ -8,12 +8,14 @@ pub enum Event { }, EndTask { task: String, + result: TaskResult, + }, + Status { + task: String, + status: String, }, Stop, Tick, - Log { - message: Vec, - }, Up, Down, ScrollUp, @@ -27,6 +29,15 @@ pub enum Event { Input { bytes: Vec, }, + UpdateTasks { + tasks: Vec, + }, +} + +#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] +pub enum TaskResult { + Success, + Failure, } #[cfg(test)] diff --git a/crates/turborepo-ui/src/tui/handle.rs b/crates/turborepo-ui/src/tui/handle.rs index 42f166e7a30ad..65359d902f941 100644 --- a/crates/turborepo-ui/src/tui/handle.rs +++ b/crates/turborepo-ui/src/tui/handle.rs @@ -3,8 +3,7 @@ use std::{ time::Instant, }; -use super::Event; -use crate::LineWriter; +use super::{Event, TaskResult}; /// Struct for sending app events to TUI rendering #[derive(Debug, Clone)] @@ -25,17 +24,6 @@ pub struct TuiTask { logs: Arc>>, } -/// Writer that will correctly render writes to the persisted part of the screen -pub struct PersistedWriter { - writer: LineWriter, -} - -/// Writer that will correctly render writes to the persisted part of the screen -#[derive(Debug, Clone)] -pub struct PersistedWriterInner { - handle: AppSender, -} - impl AppSender { /// Create a new channel for sending app events. /// @@ -68,6 +56,11 @@ impl AppSender { // it'll be a no-op. self.primary.send(Event::Stop).ok(); } + + /// Update the list of tasks displayed in the TUI + pub fn update_tasks(&self, tasks: Vec) -> Result<(), mpsc::SendError> { + self.primary.send(Event::UpdateTasks { tasks }) + } } impl AppReceiver { @@ -99,11 +92,21 @@ impl TuiTask { } /// Mark the task as finished - pub fn finish(&self) -> Vec { + pub fn succeeded(&self) -> Vec { + self.finish(TaskResult::Success) + } + + /// Mark the task as finished + pub fn failed(&self) -> Vec { + self.finish(TaskResult::Failure) + } + + fn finish(&self, result: TaskResult) -> Vec { self.handle .primary .send(Event::EndTask { task: self.name.clone(), + result, }) .ok(); self.logs.lock().expect("logs lock poisoned").clone() @@ -119,18 +122,18 @@ impl TuiTask { .ok(); } - /// Return a `PersistedWriter` which will properly write provided bytes to - /// a persisted section of the terminal. - /// - /// Designed to be a drop in replacement for `io::stdout()`, - /// all calls such as `writeln!(io::stdout(), "hello")` should - /// pass in a PersistedWriter instead. - pub fn stdout(&self) -> PersistedWriter { - PersistedWriter { - writer: LineWriter::new(PersistedWriterInner { - handle: self.as_app().clone(), - }), - } + pub fn status(&self, status: &str) { + // Since this will be rendered via ratatui we any ANSI escape codes will not be + // handled. + // TODO: prevent the status from having ANSI codes in this scenario + let status = console::strip_ansi_codes(status).into_owned(); + self.handle + .primary + .send(Event::Status { + task: self.name.clone(), + status, + }) + .ok(); } } @@ -157,28 +160,3 @@ impl std::io::Write for TuiTask { Ok(()) } } - -impl std::io::Write for PersistedWriter { - fn write(&mut self, buf: &[u8]) -> std::io::Result { - self.writer.write(buf) - } - - fn flush(&mut self) -> std::io::Result<()> { - self.writer.flush() - } -} - -impl std::io::Write for PersistedWriterInner { - fn write(&mut self, buf: &[u8]) -> std::io::Result { - let bytes = buf.to_vec(); - self.handle - .primary - .send(Event::Log { message: bytes }) - .map_err(|_| std::io::Error::new(std::io::ErrorKind::Other, "receiver dropped"))?; - Ok(buf.len()) - } - - fn flush(&mut self) -> std::io::Result<()> { - Ok(()) - } -} diff --git a/crates/turborepo-ui/src/tui/input.rs b/crates/turborepo-ui/src/tui/input.rs index d318f41ab10f8..4e47c00214ecd 100644 --- a/crates/turborepo-ui/src/tui/input.rs +++ b/crates/turborepo-ui/src/tui/input.rs @@ -23,7 +23,7 @@ pub fn input(interact: bool) -> Result, Error> { } } -/// Converts a crostterm key event into a TUI interaction event +/// Converts a crossterm key event into a TUI interaction event fn translate_key_event(interact: bool, key_event: KeyEvent) -> Option { // On Windows events for releasing a key are produced // We skip these to avoid emitting 2 events per key press. diff --git a/crates/turborepo-ui/src/tui/mod.rs b/crates/turborepo-ui/src/tui/mod.rs index 70b07b1778a85..42a8e4dab5b4b 100644 --- a/crates/turborepo-ui/src/tui/mod.rs +++ b/crates/turborepo-ui/src/tui/mod.rs @@ -1,15 +1,15 @@ mod app; -mod event; +pub mod event; mod handle; mod input; mod pane; +mod spinner; mod table; mod task; -mod task_duration; pub use app::run_app; -use event::Event; -pub use handle::{AppReceiver, AppSender, PersistedWriterInner, TuiTask}; +use event::{Event, TaskResult}; +pub use handle::{AppReceiver, AppSender, TuiTask}; use input::input; pub use pane::TerminalPane; pub use table::TaskTable; diff --git a/crates/turborepo-ui/src/tui/pane.rs b/crates/turborepo-ui/src/tui/pane.rs index 303463f00bb8e..a0bd1401966fd 100644 --- a/crates/turborepo-ui/src/tui/pane.rs +++ b/crates/turborepo-ui/src/tui/pane.rs @@ -4,20 +4,19 @@ use std::{ }; use ratatui::{ - backend::Backend, style::Style, - widgets::{ - block::{Position, Title}, - Block, Borders, Widget, - }, - Terminal, + text::Line, + widgets::{Block, Borders, Widget}, }; -use tracing::{debug, debug_span}; +use tracing::debug; use tui_term::widget::PseudoTerminal; use turborepo_vt100 as vt100; use super::{app::Direction, Error}; +const FOOTER_TEXT: &str = "Use arrow keys to navigate. Press `Enter` to interact with a task and \ + `Ctrl-Z` to stop interacting"; + pub struct TerminalPane { tasks: BTreeMap>, displayed: Option, @@ -32,6 +31,7 @@ struct TerminalOutput { parser: vt100::Parser, stdin: Option, has_been_persisted: bool, + status: Option, } impl TerminalPane { @@ -100,6 +100,12 @@ impl TerminalPane { Ok(()) } + pub fn set_status(&mut self, task: &str, status: String) -> Result<(), Error> { + let task = self.task_mut(task)?; + task.status = Some(status); + Ok(()) + } + pub fn scroll(&mut self, task: &str, direction: Direction) -> Result<(), Error> { let task = self.task_mut(task)?; let scrollback = task.parser.screen().scrollback(); @@ -111,23 +117,10 @@ impl TerminalPane { Ok(()) } - pub fn render_screen( - &mut self, - task_name: &str, - terminal: &mut Terminal, - ) -> Result<(), Error> { - let task = self.task_mut(task_name)?; - task.persist_screen(task_name, terminal) - } - - pub fn render_remaining( - &mut self, - started_tasks: HashSet<&str>, - terminal: &mut Terminal, - ) -> Result<(), Error> { + pub fn render_remaining(&mut self, started_tasks: HashSet<&str>) -> std::io::Result<()> { for (task_name, task) in self.tasks.iter_mut() { if !task.has_been_persisted && started_tasks.contains(task_name.as_str()) { - task.persist_screen(task_name, terminal)?; + task.persist_screen(task_name)?; } } Ok(()) @@ -177,6 +170,14 @@ impl TerminalOutput { rows, cols, has_been_persisted: false, + status: None, + } + } + + fn title(&self, task_name: &str) -> String { + match self.status.as_deref() { + Some(status) => format!(" {task_name} > {status} "), + None => format!(" {task_name} > "), } } @@ -188,36 +189,20 @@ impl TerminalOutput { self.cols = cols; } - #[tracing::instrument(skip(self, terminal))] - fn persist_screen( - &mut self, - task_name: &str, - terminal: &mut Terminal, - ) -> Result<(), Error> { - let mut screen = self.parser.entire_screen(); - let width = terminal.size()?.width; - // number of lines we can render before hitting the hidden area limit of ratatui - let max_lines = (u16::MAX / width).saturating_sub(2); - let (rows, _) = screen.size(); - let lines_to_render = if rows <= (max_lines as usize) { - (rows + 2) as u16 - } else { - screen.with_max_lines(Some(max_lines as usize)); - max_lines + 2 - }; - debug!("rendering {} lines", lines_to_render); - let mut cursor = tui_term::widget::Cursor::default(); - cursor.hide(); - let title = format!(" {task_name} >"); - let block = Block::default() - .borders(Borders::ALL) - .title(title.as_str()) - .title(Title::from(title.as_str()).position(Position::Bottom)); - let term = PseudoTerminal::new(&screen).cursor(cursor).block(block); - let span = debug_span!("insert before"); - let _guard = span.enter(); - terminal.insert_before(lines_to_render, |buf| term.render(buf.area, buf))?; - drop(_guard); + #[tracing::instrument(skip(self))] + fn persist_screen(&mut self, task_name: &str) -> std::io::Result<()> { + let screen = self.parser.entire_screen(); + let title = self.title(task_name); + let mut stdout = std::io::stdout().lock(); + stdout.write_all("┌".as_bytes())?; + stdout.write_all(title.as_bytes())?; + stdout.write_all(b"\r\n")?; + for row in screen.rows_formatted(0, self.cols) { + stdout.write_all("│ ".as_bytes())?; + stdout.write_all(&row)?; + stdout.write_all(b"\r\n")?; + } + stdout.write_all("└────>\r\n".as_bytes())?; self.has_been_persisted = true; Ok(()) @@ -235,7 +220,8 @@ impl Widget for &TerminalPane { let screen = task.parser.screen(); let mut block = Block::default() .borders(Borders::ALL) - .title(format!(" {task_name} >")); + .title(task.title(task_name)) + .title_bottom(Line::from(FOOTER_TEXT).centered()); if self.highlight { block = block.border_style(Style::new().fg(ratatui::style::Color::Yellow)); } @@ -273,7 +259,7 @@ mod test { "│4 │", "│5 │", "│█ │", - "└──────┘", + "└Use ar┘", ]) ); } diff --git a/crates/turborepo-ui/src/tui/spinner.rs b/crates/turborepo-ui/src/tui/spinner.rs new file mode 100644 index 0000000000000..b4c03691cc708 --- /dev/null +++ b/crates/turborepo-ui/src/tui/spinner.rs @@ -0,0 +1,68 @@ +use std::time::{Duration, Instant}; + +const SPINNER_FRAMES: &[&str] = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"].as_slice(); +const FRAMERATE: Duration = Duration::from_millis(80); + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct SpinnerState { + frame: usize, + last_render: Option, +} + +impl SpinnerState { + pub fn new() -> Self { + Self { + frame: 0, + last_render: None, + } + } + + pub fn update(&mut self) { + if let Some(last_render) = self.last_render { + if last_render.elapsed() > FRAMERATE { + self.frame = (self.frame + 1) % SPINNER_FRAMES.len(); + self.last_render = Some(Instant::now()); + } + } else { + self.last_render = Some(Instant::now()); + } + } + + pub fn current(&self) -> &'static str { + SPINNER_FRAMES[self.frame] + } +} + +impl Default for SpinnerState { + fn default() -> Self { + Self::new() + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_inital_update() { + let mut spinner = SpinnerState::new(); + assert!(spinner.last_render.is_none()); + assert_eq!(spinner.frame, 0); + spinner.update(); + assert!(spinner.last_render.is_some()); + assert_eq!(spinner.frame, 0, "initial update doesn't move frame"); + } + + #[test] + fn test_frame_update() { + let mut spinner = SpinnerState::new(); + // set last update to time that happened far before the spinner should increment + let prev_render = Instant::now() - (FRAMERATE * 2); + spinner.last_render = Some(prev_render); + assert_eq!(spinner.frame, 0); + spinner.update(); + assert_eq!(spinner.frame, 1); + let last_render = spinner.last_render.unwrap(); + assert!(prev_render < last_render, "last render should be updated"); + } +} diff --git a/crates/turborepo-ui/src/tui/table.rs b/crates/turborepo-ui/src/tui/table.rs index 67f9b149cfb8b..471aaa49c6905 100644 --- a/crates/turborepo-ui/src/tui/table.rs +++ b/crates/turborepo-ui/src/tui/table.rs @@ -1,33 +1,23 @@ -use std::time::Instant; - use ratatui::{ - buffer::Buffer, - layout::{Constraint, Layout, Rect}, - style::{Color, Style}, - text::Line, - widgets::{ - Block, BorderType, Borders, Cell, Paragraph, Row, StatefulWidget, Table, TableState, Widget, - }, + layout::{Constraint, Rect}, + style::{Color, Style, Stylize}, + text::Text, + widgets::{Cell, Row, StatefulWidget, Table, TableState}, }; use tracing::debug; use super::{ + event::TaskResult, + spinner::SpinnerState, task::{Finished, Planned, Running, Task}, - task_duration::TaskDuration, Error, }; -const FOOTER_TEXT: &str = "Use arrow keys to navigate. Press `Enter` to interact with a task and \ - `Ctrl-Z` to stop interacting"; - /// A widget that renders a table of their tasks and their current status /// /// The table contains finished tasks, running tasks, and planned tasks rendered /// in that order. pub struct TaskTable { - // Start of the run and the current time - start: Instant, - current: Instant, // Tasks to be displayed // Ordered by when they finished finished: Vec>, @@ -36,8 +26,8 @@ pub struct TaskTable { // Ordered by task name planned: Vec>, // State used for showing things - task_column_width: u16, scroll: TableState, + spinner: SpinnerState, } impl TaskTable { @@ -46,24 +36,28 @@ impl TaskTable { let mut planned = tasks.into_iter().map(Task::new).collect::>(); planned.sort_unstable(); planned.dedup(); - let task_column_width = planned - .iter() - .map(|task| task.name().len()) - .max() - .unwrap_or_default() - // Task column width should be large enough to fit "Task" title - .max(4) as u16; Self { - start: Instant::now(), - current: Instant::now(), planned, running: Vec::new(), finished: Vec::new(), - task_column_width, scroll: TableState::default(), + spinner: SpinnerState::default(), } } + // Provides a suggested width for the task table + pub fn width_hint<'a>(tasks: impl Iterator) -> u16 { + let task_name_width = tasks + .map(|task| task.len()) + .max() + .unwrap_or_default() + // Task column width should be large enough to fit "Task" title + // and truncate tasks with more than 40 chars. + .clamp(4, 40) as u16; + // Add space for column divider and status emoji + task_name_width + 1 + } + /// Number of rows in the table pub fn len(&self) -> usize { self.finished.len() + self.running.len() + self.planned.len() @@ -74,40 +68,65 @@ impl TaskTable { self.len() == 0 } - /// Mark the given planned task as started - /// Errors if given task wasn't a planned task + /// Mark the given task as started. + /// If planned, pulls it from planned tasks and starts it. + /// If finished, removes from finished and starts again as new task. pub fn start_task(&mut self, task: &str) -> Result<(), Error> { - let planned_idx = self + if let Ok(planned_idx) = self .planned .binary_search_by(|planned_task| planned_task.name().cmp(task)) - .map_err(|_| { - debug!("could not find '{task}' to start"); - Error::TaskNotFound { name: task.into() } - })?; - let planned = self.planned.remove(planned_idx); - let old_row_idx = self.finished.len() + self.running.len() + planned_idx; - let new_row_idx = self.finished.len() + self.running.len(); - let running = planned.start(); - self.running.push(running); + { + let planned = self.planned.remove(planned_idx); + let old_row_idx = self.finished.len() + self.running.len() + planned_idx; + let new_row_idx = self.finished.len() + self.running.len(); + let running = planned.start(); + self.running.push(running); - if let Some(selected_idx) = self.scroll.selected() { - // If task that was just started is selected, then update selection to follow - // task - if selected_idx == old_row_idx { - self.scroll.select(Some(new_row_idx)); - } else if new_row_idx <= selected_idx && selected_idx < old_row_idx { - // If the selected task is between the old and new row positions - // then increment the selection index to keep selection the same. - self.scroll.select(Some(selected_idx + 1)); + if let Some(selected_idx) = self.scroll.selected() { + // If task that was just started is selected, then update selection to follow + // task + if selected_idx == old_row_idx { + self.scroll.select(Some(new_row_idx)); + } else if new_row_idx <= selected_idx && selected_idx < old_row_idx { + // If the selected task is between the old and new row positions + // then increment the selection index to keep selection the same. + self.scroll.select(Some(selected_idx + 1)); + } + } + } else if let Some(finished_idx) = self + .finished + .iter() + .position(|finished_task| finished_task.name() == task) + { + let finished = self.finished.remove(finished_idx); + let old_row_idx = finished_idx; + let new_row_idx = self.finished.len() + self.running.len(); + let running = Task::new(finished.name().to_string()).start(); + self.running.push(running); + + if let Some(selected_idx) = self.scroll.selected() { + // If task that was just started is selected, then update selection to follow + // task + if selected_idx == old_row_idx { + self.scroll.select(Some(new_row_idx)); + } else if new_row_idx <= selected_idx && selected_idx < old_row_idx { + // If the selected task is between the old and new row positions + // then increment the selection index to keep selection the same. + self.scroll.select(Some(selected_idx + 1)); + } } + } else { + debug!("could not find '{task}' to start"); + return Err(Error::TaskNotFound { name: task.into() }); } + self.tick(); Ok(()) } /// Mark the given running task as finished /// Errors if given task wasn't a running task - pub fn finish_task(&mut self, task: &str) -> Result<(), Error> { + pub fn finish_task(&mut self, task: &str, result: TaskResult) -> Result<(), Error> { let running_idx = self .running .iter() @@ -119,7 +138,7 @@ impl TaskTable { let old_row_idx = self.finished.len() + running_idx; let new_row_idx = self.finished.len(); let running = self.running.remove(running_idx); - self.finished.push(running.finish()); + self.finished.push(running.finish(result)); if let Some(selected_row) = self.scroll.selected() { // If task that was just started is selected, then update selection to follow @@ -139,7 +158,7 @@ impl TaskTable { /// Update the current time of the table pub fn tick(&mut self) { - self.current = Instant::now(); + self.spinner.update(); } /// Select the next row @@ -162,8 +181,7 @@ impl TaskTable { self.scroll.select(Some(i)); } - pub fn selected(&self) -> Option<&str> { - let i = self.scroll.selected()?; + pub fn get(&self, i: usize) -> Option<&str> { if i < self.finished.len() { let task = self.finished.get(i)?; Some(task.name()) @@ -180,6 +198,11 @@ impl TaskTable { } } + pub fn selected(&self) -> Option<&str> { + let i = self.scroll.selected()?; + self.get(i) + } + pub fn tasks_started(&self) -> impl Iterator + '_ { self.finished .iter() @@ -187,72 +210,38 @@ impl TaskTable { .chain(self.running.iter().map(|task| task.name())) } - fn finished_rows(&self, duration_width: u16) -> impl Iterator + '_ { + fn finished_rows(&self) -> impl Iterator + '_ { self.finished.iter().map(move |task| { Row::new(vec![ Cell::new(task.name()), - Cell::new(TaskDuration::new( - duration_width, - self.start, - self.current, - task.start(), - Some(task.end()), - )), + Cell::new(match task.result() { + TaskResult::Success => Text::raw("✔").style(Style::default().light_green()), + TaskResult::Failure => Text::raw("✘").style(Style::default().red()), + }), ]) }) } - fn running_rows(&self, duration_width: u16) -> impl Iterator + '_ { - self.running.iter().map(move |task| { - Row::new(vec![ - Cell::new(task.name()), - Cell::new(TaskDuration::new( - duration_width, - self.start, - self.current, - task.start(), - None, - )), - ]) - }) + fn running_rows(&self) -> impl Iterator + '_ { + let spinner = self.spinner.current(); + self.running + .iter() + .map(move |task| Row::new(vec![Cell::new(task.name()), Cell::new(Text::raw(spinner))])) } - fn planned_rows(&self, duration_width: u16) -> impl Iterator + '_ { - self.planned.iter().map(move |task| { - Row::new(vec![ - Cell::new(task.name()), - Cell::new(" ".repeat(duration_width as usize)), - ]) - }) + fn planned_rows(&self) -> impl Iterator + '_ { + self.planned + .iter() + .map(move |task| Row::new(vec![Cell::new(task.name()), Cell::new(" ")])) } /// Convenience method which renders and updates scroll state pub fn stateful_render(&mut self, frame: &mut ratatui::Frame, area: Rect) { let mut scroll = self.scroll.clone(); + self.spinner.update(); frame.render_stateful_widget(&*self, area, &mut scroll); self.scroll = scroll; } - - fn column_widths(&self, parent_width: u16) -> (u16, u16) { - // We trim names to be 40 long (+1 for column divider) - let name_col_width = 40.min(self.task_column_width) + 1; - if name_col_width + 2 < parent_width { - let status_width = parent_width - (name_col_width + 2); - (name_col_width, status_width) - } else { - // If there isn't any space for the task status, just don't display anything - (name_col_width, 0) - } - } - - fn render_footer(area: Rect, buf: &mut Buffer) { - let footer = Paragraph::new(Line::from(FOOTER_TEXT)).centered().block( - Block::default() - .borders(Borders::TOP) - .border_type(BorderType::Plain), - ); - footer.render(area, buf); - } } impl<'a> StatefulWidget for &'a TaskTable { @@ -260,41 +249,32 @@ impl<'a> StatefulWidget for &'a TaskTable { fn render(self, area: Rect, buf: &mut ratatui::prelude::Buffer, state: &mut Self::State) { let width = area.width; - let (name_width, status_width) = self.column_widths(width); - let areas = Layout::default() - .direction(ratatui::layout::Direction::Vertical) - .constraints([Constraint::Min(2), Constraint::Length(2)]) - .split(area); + let bar = "─".repeat(usize::from(width)); let table = Table::new( - self.finished_rows(status_width) - .chain(self.running_rows(status_width)) - .chain(self.planned_rows(status_width)), + self.finished_rows() + .chain(self.running_rows()) + .chain(self.planned_rows()), [ - Constraint::Min(name_width), - Constraint::Length(status_width), + Constraint::Min(4), + // Status takes one cell to render + Constraint::Length(1), ], ) .highlight_style(Style::default().fg(Color::Yellow)) + .column_spacing(0) .header( - ["Task\n----", "Status\n------"] - .iter() - .copied() + vec![format!("Task\n{bar}"), "\n─".to_owned()] + .into_iter() .map(Cell::from) .collect::() .height(2), ); - StatefulWidget::render(table, areas[0], buf, state); - TaskTable::render_footer(areas[1], buf); + StatefulWidget::render(table, area, buf, state); } } #[cfg(test)] mod test { - // Used by assert_buffer_eq - #[allow(unused_imports)] - use indoc::indoc; - use ratatui::assert_buffer_eq; - use super::*; #[test] @@ -329,11 +309,52 @@ mod test { table.start_task("a").unwrap(); assert_eq!(table.scroll.selected(), Some(0), "b stays selected"); assert_eq!(table.selected(), Some("b"), "selected b"); - table.finish_task("a").unwrap(); + table.finish_task("a", TaskResult::Success).unwrap(); assert_eq!(table.scroll.selected(), Some(1), "b stays selected"); assert_eq!(table.selected(), Some("b"), "selected b"); } + #[test] + fn test_restart_task() { + let mut table = TaskTable::new(vec!["a".to_string(), "b".to_string(), "c".to_string()]); + table.next(); + table.next(); + // Start all tasks + table.start_task("b").unwrap(); + table.start_task("a").unwrap(); + table.start_task("c").unwrap(); + assert_eq!(table.get(0), Some("b"), "b is on top (running)"); + table.finish_task("a", TaskResult::Success).unwrap(); + assert_eq!( + (table.get(0), table.get(1)), + (Some("a"), Some("b")), + "a is on top (done), b is second (running)" + ); + + table.finish_task("b", TaskResult::Success).unwrap(); + assert_eq!( + (table.get(0), table.get(1)), + (Some("a"), Some("b")), + "a is on top (done), b is second (done)" + ); + + // Restart b + table.start_task("b").unwrap(); + assert_eq!( + (table.get(1), table.get(2)), + (Some("c"), Some("b")), + "b is third (running)" + ); + + // Restart a + table.start_task("a").unwrap(); + assert_eq!( + (table.get(0), table.get(1), table.get(2)), + (Some("c"), Some("b"), Some("a")), + "c is on top (running), b is second (running), a is third (running)" + ); + } + #[test] fn test_selection_stable() { let mut table = TaskTable::new(vec!["a".to_string(), "b".to_string(), "c".to_string()]); @@ -355,31 +376,12 @@ mod test { table.previous(); assert_eq!(table.scroll.selected(), Some(0), "selected c"); assert_eq!(table.selected(), Some("c"), "selected c"); - table.finish_task("a").unwrap(); + table.finish_task("a", TaskResult::Success).unwrap(); assert_eq!(table.scroll.selected(), Some(1), "c stays selected"); assert_eq!(table.selected(), Some("c"), "selected c"); table.previous(); - table.finish_task("c").unwrap(); + table.finish_task("c", TaskResult::Success).unwrap(); assert_eq!(table.scroll.selected(), Some(0), "a stays selected"); assert_eq!(table.selected(), Some("a"), "selected a"); } - - #[test] - fn test_footer_always_rendered() { - let table = TaskTable::new(vec!["a".to_string(), "b".to_string(), "c".to_string()]); - let area = Rect::new(0, 0, 14, 5); - let mut buffer = Buffer::empty(area); - let mut scroll = table.scroll.clone(); - StatefulWidget::render(&table, area, &mut buffer, &mut scroll); - assert_buffer_eq!( - buffer, - Buffer::with_lines(vec![ - "Task Status ", - "---- ------ ", - "a ", - "──────────────", - "Use arrow keys", - ]) - ) - } } diff --git a/crates/turborepo-ui/src/tui/task.rs b/crates/turborepo-ui/src/tui/task.rs index cf96ac1ec2241..9f514bc7b8697 100644 --- a/crates/turborepo-ui/src/tui/task.rs +++ b/crates/turborepo-ui/src/tui/task.rs @@ -1,5 +1,8 @@ +#![allow(dead_code)] use std::time::Instant; +use super::event::TaskResult; + #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] pub struct Planned; @@ -12,6 +15,7 @@ pub struct Running { pub struct Finished { start: Instant, end: Instant, + result: TaskResult, } #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)] @@ -45,7 +49,7 @@ impl Task { } impl Task { - pub fn finish(self) -> Task { + pub fn finish(self, result: TaskResult) -> Task { let Task { name, state: Running { start }, @@ -54,6 +58,7 @@ impl Task { name, state: Finished { start, + result, end: Instant::now(), }, } @@ -72,4 +77,8 @@ impl Task { pub fn end(&self) -> Instant { self.state.end } + + pub fn result(&self) -> TaskResult { + self.state.result + } } diff --git a/crates/turborepo-ui/src/tui/task_duration.rs b/crates/turborepo-ui/src/tui/task_duration.rs deleted file mode 100644 index b1dfc13af5625..0000000000000 --- a/crates/turborepo-ui/src/tui/task_duration.rs +++ /dev/null @@ -1,118 +0,0 @@ -use std::time::Instant; - -use ratatui::text::Text; - -#[derive(Debug, Clone, Copy)] -pub struct TaskDuration { - width: u16, - run_start: Instant, - current: Instant, - task_start: Instant, - task_end: Option, -} - -impl TaskDuration { - pub fn new( - width: u16, - run_start: Instant, - current: Instant, - task_start: Instant, - task_end: Option, - ) -> Self { - Self { - width, - run_start, - current, - task_start, - task_end, - } - } - - fn run_duration_ms(&self) -> u128 { - self.current.duration_since(self.run_start).as_millis() - } - - fn start_offset(&self) -> u128 { - self.task_start.duration_since(self.run_start).as_millis() - } - - fn end_offset(&self) -> u128 { - self.task_end - .unwrap_or(self.current) - .duration_since(self.run_start) - .as_millis() - } - - fn end_marker(&self) -> char { - match self.task_end.is_some() { - true => '|', - false => '>', - } - } - - fn scale(&self) -> f64 { - self.width as f64 / self.run_duration_ms() as f64 - } -} - -impl From for Text<'static> { - fn from(value: TaskDuration) -> Self { - let scale = value.scale(); - let last_index = value.width - 1; - // We clamp these to the last visible char in the case either of events happen - // to be happen at the 'current' instant. - let start_index = ((value.start_offset() as f64 * scale) as u16).min(last_index); - let end_index = ((value.end_offset() as f64 * scale) as u16).min(last_index); - - let mut bar = String::with_capacity(value.width.into()); - for idx in 0..value.width { - if idx < start_index { - bar.push(' '); - } else if idx == start_index { - bar.push('|'); - } else if start_index < idx && idx < end_index { - bar.push('-'); - } else if idx == end_index { - bar.push(value.end_marker()); - } else { - bar.push(' '); - } - } - Text::raw(bar) - } -} - -#[cfg(test)] -mod test { - use std::time::Duration; - - use ratatui::{buffer::Buffer, layout::Rect, widgets::Widget}; - use test_case::test_case; - - use super::*; - - #[test_case("|-------->", 0, None ; "full bar")] - #[test_case(" |--| ", 2, Some(5) ; "finished task")] - #[test_case(" |--->", 5, None ; "late unfinished")] - #[test_case(" | ", 5, Some(5) ; "short task")] - #[test_case(" || ", 5, Some(6) ; "no inner")] - #[test_case(" |", 10, None ; "just started")] - fn task_duration_render(expected: &str, start: u64, end: Option) { - let width = 10; - let run_start = Instant::now(); - let current = run_start + Duration::from_secs(10); - let task_start = run_start + Duration::from_secs(start); - let task_end = end.map(|end| run_start + Duration::from_secs(end)); - let duration = TaskDuration { - width, - run_start, - current, - task_start, - task_end, - }; - let text = Text::from(duration); - let mut buffer = Buffer::empty(Rect::new(0, 0, width, 1)); - text.render(buffer.area, &mut buffer); - assert_eq!(buffer, Buffer::with_lines(vec![expected])); - } -} diff --git a/crates/turborepo-vt100/src/entire_screen.rs b/crates/turborepo-vt100/src/entire_screen.rs index 3c9ba4d4556d0..1938cf04170a9 100644 --- a/crates/turborepo-vt100/src/entire_screen.rs +++ b/crates/turborepo-vt100/src/entire_screen.rs @@ -1,7 +1,8 @@ +use crate::term::BufWrite; +use std::io::Write; + pub struct EntireScreen<'a> { screen: &'a crate::Screen, - // If present, screen will be truncated to only display lines that fit in those cells - max_lines: Option, size: (usize, u16), } @@ -11,30 +12,12 @@ impl<'a> EntireScreen<'a> { Self { size: screen.grid().size_with_contents(), screen, - max_lines: None, } } - pub fn with_max_lines(&mut self, max_lines: Option) { - self.max_lines = max_lines; - } - #[must_use] pub fn cell(&self, row: u16, col: u16) -> Option<&crate::Cell> { - match self.max_lines { - // We need to do some trimming - Some(max_lines) if self.size().0 > max_lines => { - // in this case we fuck ourselves :) HARD - let (height, _) = self.size(); - // Skip over these - let lines_to_cut = (height - max_lines) as u16; - self.screen - .grid() - .all_row(lines_to_cut + row) - .and_then(|r| r.get(col)) - } - _ => self.screen.grid().all_row(row).and_then(|r| r.get(col)), - } + self.screen.grid().all_row(row).and_then(|r| r.get(col)) } #[must_use] @@ -44,6 +27,53 @@ impl<'a> EntireScreen<'a> { s } + /// Returns the formatted contents of the terminal by row, + /// restricted to the given subset of columns. + /// + /// Formatting information will be included inline as terminal escape + /// codes. The result will be suitable for feeding directly to a raw + /// terminal parser, and will result in the same visual output. + /// + /// You are responsible for positioning the cursor before printing each + /// row, and the final cursor position after displaying each row is + /// unspecified. + // the unwraps in this method shouldn't be reachable + #[allow(clippy::missing_panics_doc)] + pub fn rows_formatted( + &self, + start: u16, + width: u16, + ) -> impl Iterator> + '_ { + let mut wrapping = false; + let grid = self.screen.grid(); + let (rows, _) = self.size(); + let default = crate::attrs::Attrs::default(); + grid.all_rows().take(rows).enumerate().map(move |(i, row)| { + // number of rows in a grid is stored in a u16 (see Size), so + // visible_rows can never return enough rows to overflow here + let i = i.try_into().unwrap(); + let mut contents = vec![]; + // We don't need final cursor position as long as CRLF is used and not just LF + let (_pos, attrs) = row.write_contents_formatted( + &mut contents, + start, + width, + i, + wrapping, + None, + None, + ); + if start == 0 && width == grid.size().cols { + wrapping = row.wrapped(); + } + // If the row ended in non-default attributes, then clear them + if attrs != default { + crate::term::ClearAttrs.write_buf(&mut contents); + } + contents + }) + } + /// Size required to render all contents #[must_use] pub fn size(&self) -> (usize, u16) { diff --git a/docs/pages/repo/docs/core-concepts/monorepos/configuring-workspaces.mdx b/docs/pages/repo/docs/core-concepts/monorepos/configuring-workspaces.mdx index b82333f573b30..96b4d7a52ce98 100644 --- a/docs/pages/repo/docs/core-concepts/monorepos/configuring-workspaces.mdx +++ b/docs/pages/repo/docs/core-concepts/monorepos/configuring-workspaces.mdx @@ -30,14 +30,14 @@ key: // custom configuration for the build task in this workspace }, // new tasks only available in this workspace - "special-task": {}, + "special-task": {} } } ``` - For now, the only valid value for the `extends` key is `["//"]`. -`//` is a special name used to identify the root directory of the monorepo. + For now, the only valid value for the `extends` key is `["//"]`. `//` is a + special name used to identify the root directory of the monorepo. Configuration in a workspace can override any of [the configurations for a @@ -59,7 +59,7 @@ with a single `turbo.json` at the root like this: { "pipeline": { "build": { - "outputs": [".next/**", "!.next/cache/**", ".svelte-kit/**"], + "outputs": [".next/**", "!.next/cache/**", ".svelte-kit/**"] } } } @@ -152,8 +152,8 @@ but continue to inherit any other tasks defined at the root. At first glance, Workspace Configurations may sound a lot like the [`workspace#task` syntax][3] in the root `turbo.json`. The features are similar, but have one significant difference: when you declare a Workspace-specific -in the root `turbo.json`, it _completely_ overwrites the baseline task -configuration. With a Workspace Configuration, the task configuration is merged +task configuration in the root `turbo.json`, it _completely_ overwrites the baseline +task configuration. With a Workspace Configuration, the task configuration is merged instead. Consider the example of the monorepo with multiple Next.js apps and a Sveltekit @@ -166,7 +166,7 @@ app again. Without a Workspace-specific task, you might configure your root "build": { "outputMode": "hash-only", "inputs": ["src/**"], - "outputs": [".next/**", "!.next/cache/**"], + "outputs": [".next/**", "!.next/cache/**"] }, "my-sveltekit-app#build": { "outputMode": "hash-only", // must duplicate this @@ -186,7 +186,8 @@ you don't need to duplicate them. You only need to override `outputs` Although there are no plans to remove Workspace-specific task configurations, - we expect that Workspace Configurations can be used for most use cases instead. + we expect that Workspace Configurations can be used for most use cases + instead. ## Limitations @@ -218,7 +219,7 @@ they are intentional, rather than accidental: }, "build": { // ✅ just use the task name! - }, + } } } ``` @@ -231,7 +232,7 @@ they are intentional, rather than accidental: "build": { // ✅ It's still ok to have workspace#task in dependsOn! "dependsOn": ["some-pkg#compile"] - }, + } } } ``` diff --git a/docs/pages/repo/docs/core-concepts/monorepos/running-tasks.mdx b/docs/pages/repo/docs/core-concepts/monorepos/running-tasks.mdx index a263cc53d23ee..bb304f8ad864a 100644 --- a/docs/pages/repo/docs/core-concepts/monorepos/running-tasks.mdx +++ b/docs/pages/repo/docs/core-concepts/monorepos/running-tasks.mdx @@ -5,7 +5,7 @@ description: Turborepo can run all your tasks. import { Callout } from "../../../../../components/Callout"; import HeartIcon from "@heroicons/react/solid/HeartIcon"; -import { Tabs, Tab } from '../../../../../components/Tabs' +import { Tabs, Tab } from "../../../../../components/Tabs"; # Running Tasks in a Monorepo @@ -94,10 +94,10 @@ monorepo. Here's a kitchen sink example: "outputs": [".next/**", "!.next/cache/**", ".svelte-kit/**"] }, "deploy": { - // A workspace's `deploy` task depends on the `build`, - // `test`, and `lint` tasks of the same workspace - // being completed. - "dependsOn": ["build", "test", "lint"] + // A workspace's `deploy` task depends on the `build`, + // `test`, and `lint` tasks of the same workspace + // being completed. + "dependsOn": ["build", "test", "lint"] }, "test": { // A workspace's `test` task depends on that workspace's @@ -140,12 +140,12 @@ A sample pipeline that defines the root task `format` and opts the root into `te "outputs": [".next/**", "!.next/cache/**", ".svelte-kit/**"] }, "test": { - "dependsOn": ["^build"], + "dependsOn": ["^build"] }, // This will cause the "test" script to be included when // "turbo run test" is run "//#test": { - "dependsOn": [], + "dependsOn": [] }, // This will cause the "format" script in the root package.json // to be run when "turbo run format" is run. Since the general @@ -171,7 +171,7 @@ opt in those tasks which don't themselves trigger a `turbo` run that would recur After you've declared a task in `turbo.json`, it's up to you to implement it in your `package.json` manifests. You can add scripts all at once, or one workspace -at at a time. Turborepo will gracefully skip workspaces that don't include the +at a time. Turborepo will gracefully skip workspaces that don't include the task in their respective package.json manifest. For example, if your repository has the three workspaces (similar to the ones mentioned above): @@ -247,6 +247,6 @@ A turbo build will only execute the `build` script for the `web` and `docs` work Turborepo's Pipeline API design and this page of documentation was inspired by [Microsoft's Lage project](https://microsoft.github.io/lage/docs/Tutorial/pipeline#defining-a-pipeline). - Shoutout to [Kenneth Chau](https://x.com/kenneth_chau) for the idea of - fanning out tasks in such a concise and elegant way. + Shoutout to [Kenneth Chau](https://x.com/kenneth_chau) for the idea of fanning + out tasks in such a concise and elegant way. diff --git a/docs/pages/repo/docs/handbook/linting/eslint.mdx b/docs/pages/repo/docs/handbook/linting/eslint.mdx index d6fa688791449..35b50ab08ddf7 100644 --- a/docs/pages/repo/docs/handbook/linting/eslint.mdx +++ b/docs/pages/repo/docs/handbook/linting/eslint.mdx @@ -1,5 +1,5 @@ import { Tabs, Tab } from "../../../../../components/Tabs"; -import { Callout } from '../../../../../components/Callout' +import { Callout } from "../../../../../components/Callout"; # ESLint in a monorepo @@ -22,21 +22,21 @@ apps ├─ package.json └─ .eslintrc.js packages -└─ eslint-config-custom +└─ eslint-config ├─ next.js ├─ library.js └─ package.json ``` -We've got a package called `eslint-config-custom`, and two applications, each with their own `.eslintrc.js`. +We've got a package called `@repo/eslint-config`, and two applications, each with their own `.eslintrc.js`. -### Our `eslint-config-custom` package +### Our `@repo/eslint-config` package -Our `eslint-config-custom` file contains two files, `next.js`, and `library.js`. These are two different ESLint configs, which we can use in different workspaces, depending on our needs. +Our `@repo/eslint-config` file contains two files, `next.js`, and `library.js`. These are two different ESLint configs, which we can use in different workspaces, depending on our needs. Let's investigate the `next.js` lint configuration: -```js filename="packages/eslint-config-custom/next.js" +```js filename="packages/eslint-config/next.js" const { resolve } = require("node:path"); const project = resolve(process.cwd(), "tsconfig.json"); @@ -87,9 +87,9 @@ It's a typical ESLint config that extends the [Vercel styleguide](https://github The `package.json` looks like this: -```json filename="packages/eslint-config-custom/package.json" +```json filename="packages/eslint-config/package.json" { - "name": "eslint-config-custom", + "name": "@repo/eslint-config", "license": "MIT", "version": "0.0.0", "private": true, @@ -98,21 +98,20 @@ The `package.json` looks like this: "eslint-config-turbo": "^1.10.12" } } - ``` -Note that the ESLint dependencies are all listed here. This is useful - it means we don't need to re-specify the dependencies inside the apps which import `eslint-config-custom`. +Note that the ESLint dependencies are all listed here. This is useful - it means we don't need to re-specify the dependencies inside the apps which import `@repo/eslint-config`. -### How to use the `eslint-config-custom` package +### How to use the `@repo/eslint-config` package -In our `web` app, we first need to add `eslint-config-custom` as a dependency. +In our `web` app, we first need to add `@repo/eslint-config` as a dependency. ```jsonc filename="apps/web/package.json" { "dependencies": { - "eslint-config-custom": "*" + "@repo/eslint-config": "*" } } ``` @@ -121,7 +120,7 @@ In our `web` app, we first need to add `eslint-config-custom` as a dependency. ```jsonc filename="apps/web/package.json" { "dependencies": { - "eslint-config-custom": "*" + "@repo/eslint-config": "*" } } ``` @@ -130,7 +129,7 @@ In our `web` app, we first need to add `eslint-config-custom` as a dependency. ```jsonc filename="apps/web/package.json" { "dependencies": { - "eslint-config-custom": "workspace:*" + "@repo/eslint-config": "workspace:*" } } ``` @@ -142,15 +141,11 @@ We can then import the config like this: ```js filename="apps/web/.eslintrc.js" module.exports = { root: true, - extends: ["custom/next"], + extends: ["@repo/eslint-config/next.js"], }; ``` -By adding `custom/next` to our `extends` array, we're telling ESLint to look for a package called `eslint-config-custom`, and reference the file `next.js`. - - - You can avoid specifying the file by setting the entrypoint for your package. For example, setting `main: 'next.js'` in the `package.json`, could be loaded as simply `extends: ["custom"]` in your `.eslintrc.js`. - +By adding `@repo/eslint-config/next.js` to our `extends` array, we're telling ESLint to look for a package called `@repo/eslint-config`, and reference the file `next.js`. ### Summary diff --git a/examples/basic/packages/eslint-config/react-internal.js b/examples/basic/packages/eslint-config/react-internal.js index f56c9249e7729..0b53f12c987bf 100644 --- a/examples/basic/packages/eslint-config/react-internal.js +++ b/examples/basic/packages/eslint-config/react-internal.js @@ -6,10 +6,6 @@ const project = resolve(process.cwd(), "tsconfig.json"); * This is a custom ESLint configuration for use with * internal (bundled by their consumer) libraries * that utilize React. - * - * This config extends the Vercel Engineering Style Guide. - * For more information, see https://github.com/vercel/style-guide - * */ /** @type {import("eslint").Linter.Config} */ diff --git a/examples/kitchen-sink/packages/config-eslint/remix.js b/examples/kitchen-sink/packages/config-eslint/remix.js index bd3511549e77d..aa46f7a1fa5e5 100644 --- a/examples/kitchen-sink/packages/config-eslint/remix.js +++ b/examples/kitchen-sink/packages/config-eslint/remix.js @@ -5,10 +5,6 @@ const project = resolve(process.cwd(), "tsconfig.json"); /* * This is a custom ESLint configuration for use a library * that utilizes React. - * - * This config extends the Vercel Engineering Style Guide. - * For more information, see https://github.com/vercel/style-guide - * */ module.exports = { diff --git a/examples/with-berry/packages/eslint-config/react-internal.js b/examples/with-berry/packages/eslint-config/react-internal.js index f56c9249e7729..0b53f12c987bf 100644 --- a/examples/with-berry/packages/eslint-config/react-internal.js +++ b/examples/with-berry/packages/eslint-config/react-internal.js @@ -6,10 +6,6 @@ const project = resolve(process.cwd(), "tsconfig.json"); * This is a custom ESLint configuration for use with * internal (bundled by their consumer) libraries * that utilize React. - * - * This config extends the Vercel Engineering Style Guide. - * For more information, see https://github.com/vercel/style-guide - * */ /** @type {import("eslint").Linter.Config} */ diff --git a/examples/with-changesets/packages/eslint-config/react-internal.js b/examples/with-changesets/packages/eslint-config/react-internal.js index f56c9249e7729..0b53f12c987bf 100644 --- a/examples/with-changesets/packages/eslint-config/react-internal.js +++ b/examples/with-changesets/packages/eslint-config/react-internal.js @@ -6,10 +6,6 @@ const project = resolve(process.cwd(), "tsconfig.json"); * This is a custom ESLint configuration for use with * internal (bundled by their consumer) libraries * that utilize React. - * - * This config extends the Vercel Engineering Style Guide. - * For more information, see https://github.com/vercel/style-guide - * */ /** @type {import("eslint").Linter.Config} */ diff --git a/examples/with-docker/packages/eslint-config/react-internal.js b/examples/with-docker/packages/eslint-config/react-internal.js index f56c9249e7729..0b53f12c987bf 100644 --- a/examples/with-docker/packages/eslint-config/react-internal.js +++ b/examples/with-docker/packages/eslint-config/react-internal.js @@ -6,10 +6,6 @@ const project = resolve(process.cwd(), "tsconfig.json"); * This is a custom ESLint configuration for use with * internal (bundled by their consumer) libraries * that utilize React. - * - * This config extends the Vercel Engineering Style Guide. - * For more information, see https://github.com/vercel/style-guide - * */ /** @type {import("eslint").Linter.Config} */ diff --git a/examples/with-gatsby/packages/eslint-config/react-internal.js b/examples/with-gatsby/packages/eslint-config/react-internal.js index f56c9249e7729..0b53f12c987bf 100644 --- a/examples/with-gatsby/packages/eslint-config/react-internal.js +++ b/examples/with-gatsby/packages/eslint-config/react-internal.js @@ -6,10 +6,6 @@ const project = resolve(process.cwd(), "tsconfig.json"); * This is a custom ESLint configuration for use with * internal (bundled by their consumer) libraries * that utilize React. - * - * This config extends the Vercel Engineering Style Guide. - * For more information, see https://github.com/vercel/style-guide - * */ /** @type {import("eslint").Linter.Config} */ diff --git a/examples/with-npm/packages/eslint-config/react-internal.js b/examples/with-npm/packages/eslint-config/react-internal.js index f56c9249e7729..0b53f12c987bf 100644 --- a/examples/with-npm/packages/eslint-config/react-internal.js +++ b/examples/with-npm/packages/eslint-config/react-internal.js @@ -6,10 +6,6 @@ const project = resolve(process.cwd(), "tsconfig.json"); * This is a custom ESLint configuration for use with * internal (bundled by their consumer) libraries * that utilize React. - * - * This config extends the Vercel Engineering Style Guide. - * For more information, see https://github.com/vercel/style-guide - * */ /** @type {import("eslint").Linter.Config} */ diff --git a/examples/with-prisma/packages/database/package.json b/examples/with-prisma/packages/database/package.json index ed15ee1abb14a..d9885a5b25fa4 100644 --- a/examples/with-prisma/packages/database/package.json +++ b/examples/with-prisma/packages/database/package.json @@ -9,7 +9,7 @@ "db:migrate:dev": "prisma migrate dev", "db:push": "prisma db push", "db:seed": "tsx src/seed.ts", - "dev": "tsup --watch", + "dev": "tsup src/* --watch", "format": "prisma format", "generate": "prisma generate", "lint": "eslint . --max-warnings 0", @@ -22,10 +22,11 @@ }, "devDependencies": { "@repo/eslint-config": "*", + "@repo/typescript-config": "*", "eslint": "^8.57.0", "prisma": "^5.10.2", "rimraf": "^5.0.5", - "@repo/typescript-config": "*", + "tsup": "^8.0.2", "tsx": "^4.7.1", "typescript": "^5.3.3" } diff --git a/examples/with-prisma/packages/database/src/seed.ts b/examples/with-prisma/packages/database/src/seed.ts index a5d7752cd5e08..dc1a70b11d898 100644 --- a/examples/with-prisma/packages/database/src/seed.ts +++ b/examples/with-prisma/packages/database/src/seed.ts @@ -1,4 +1,4 @@ -import { prisma } from "."; +import { prisma } from "./client"; import type { User } from "@prisma/client"; diff --git a/examples/with-prisma/yarn.lock b/examples/with-prisma/yarn.lock index ecd07568dac2d..25788b9331a80 100644 --- a/examples/with-prisma/yarn.lock +++ b/examples/with-prisma/yarn.lock @@ -564,6 +564,86 @@ dependencies: "@prisma/debug" "5.10.2" +"@rollup/rollup-android-arm-eabi@4.16.4": + version "4.16.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.16.4.tgz#5e8930291f1e5ead7fb1171d53ba5c87718de062" + integrity sha512-GkhjAaQ8oUTOKE4g4gsZ0u8K/IHU1+2WQSgS1TwTcYvL+sjbaQjNHFXbOJ6kgqGHIO1DfUhI/Sphi9GkRT9K+Q== + +"@rollup/rollup-android-arm64@4.16.4": + version "4.16.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.16.4.tgz#ffb84f1359c04ec8a022a97110e18a5600f5f638" + integrity sha512-Bvm6D+NPbGMQOcxvS1zUl8H7DWlywSXsphAeOnVeiZLQ+0J6Is8T7SrjGTH29KtYkiY9vld8ZnpV3G2EPbom+w== + +"@rollup/rollup-darwin-arm64@4.16.4": + version "4.16.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.16.4.tgz#b2fcee8d4806a0b1b9185ac038cc428ddedce9f4" + integrity sha512-i5d64MlnYBO9EkCOGe5vPR/EeDwjnKOGGdd7zKFhU5y8haKhQZTN2DgVtpODDMxUr4t2K90wTUJg7ilgND6bXw== + +"@rollup/rollup-darwin-x64@4.16.4": + version "4.16.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.16.4.tgz#fcb25ccbaa3dd33a6490e9d1c64bab2e0e16b932" + integrity sha512-WZupV1+CdUYehaZqjaFTClJI72fjJEgTXdf4NbW69I9XyvdmztUExBtcI2yIIU6hJtYvtwS6pkTkHJz+k08mAQ== + +"@rollup/rollup-linux-arm-gnueabihf@4.16.4": + version "4.16.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.16.4.tgz#40d46bdfe667e5eca31bf40047460e326d2e26bb" + integrity sha512-ADm/xt86JUnmAfA9mBqFcRp//RVRt1ohGOYF6yL+IFCYqOBNwy5lbEK05xTsEoJq+/tJzg8ICUtS82WinJRuIw== + +"@rollup/rollup-linux-arm-musleabihf@4.16.4": + version "4.16.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.16.4.tgz#7741df2448c11c56588b50835dbfe91b1a10b375" + integrity sha512-tJfJaXPiFAG+Jn3cutp7mCs1ePltuAgRqdDZrzb1aeE3TktWWJ+g7xK9SNlaSUFw6IU4QgOxAY4rA+wZUT5Wfg== + +"@rollup/rollup-linux-arm64-gnu@4.16.4": + version "4.16.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.16.4.tgz#0a23b02d2933e4c4872ad18d879890b6a4a295df" + integrity sha512-7dy1BzQkgYlUTapDTvK997cgi0Orh5Iu7JlZVBy1MBURk7/HSbHkzRnXZa19ozy+wwD8/SlpJnOOckuNZtJR9w== + +"@rollup/rollup-linux-arm64-musl@4.16.4": + version "4.16.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.16.4.tgz#e37ef259358aa886cc07d782220a4fb83c1e6970" + integrity sha512-zsFwdUw5XLD1gQe0aoU2HVceI6NEW7q7m05wA46eUAyrkeNYExObfRFQcvA6zw8lfRc5BHtan3tBpo+kqEOxmg== + +"@rollup/rollup-linux-powerpc64le-gnu@4.16.4": + version "4.16.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.16.4.tgz#8c69218b6de05ee2ba211664a2d2ac1e54e43f94" + integrity sha512-p8C3NnxXooRdNrdv6dBmRTddEapfESEUflpICDNKXpHvTjRRq1J82CbU5G3XfebIZyI3B0s074JHMWD36qOW6w== + +"@rollup/rollup-linux-riscv64-gnu@4.16.4": + version "4.16.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.16.4.tgz#d32727dab8f538d9a4a7c03bcf58c436aecd0139" + integrity sha512-Lh/8ckoar4s4Id2foY7jNgitTOUQczwMWNYi+Mjt0eQ9LKhr6sK477REqQkmy8YHY3Ca3A2JJVdXnfb3Rrwkng== + +"@rollup/rollup-linux-s390x-gnu@4.16.4": + version "4.16.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.16.4.tgz#d46097246a187d99fc9451fe8393b7155b47c5ec" + integrity sha512-1xwwn9ZCQYuqGmulGsTZoKrrn0z2fAur2ujE60QgyDpHmBbXbxLaQiEvzJWDrscRq43c8DnuHx3QorhMTZgisQ== + +"@rollup/rollup-linux-x64-gnu@4.16.4": + version "4.16.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.16.4.tgz#6356c5a03a4afb1c3057490fc51b4764e109dbc7" + integrity sha512-LuOGGKAJ7dfRtxVnO1i3qWc6N9sh0Em/8aZ3CezixSTM+E9Oq3OvTsvC4sm6wWjzpsIlOCnZjdluINKESflJLA== + +"@rollup/rollup-linux-x64-musl@4.16.4": + version "4.16.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.16.4.tgz#03a5831a9c0d05877b94653b5ddd3020d3c6fb06" + integrity sha512-ch86i7KkJKkLybDP2AtySFTRi5fM3KXp0PnHocHuJMdZwu7BuyIKi35BE9guMlmTpwwBTB3ljHj9IQXnTCD0vA== + +"@rollup/rollup-win32-arm64-msvc@4.16.4": + version "4.16.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.16.4.tgz#6cc0db57750376b9303bdb6f5482af8974fcae35" + integrity sha512-Ma4PwyLfOWZWayfEsNQzTDBVW8PZ6TUUN1uFTBQbF2Chv/+sjenE86lpiEwj2FiviSmSZ4Ap4MaAfl1ciF4aSA== + +"@rollup/rollup-win32-ia32-msvc@4.16.4": + version "4.16.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.16.4.tgz#aea0b7e492bd9ed46971cb80bc34f1eb14e07789" + integrity sha512-9m/ZDrQsdo/c06uOlP3W9G2ENRVzgzbSXmXHT4hwVaDQhYcRpi9bgBT0FTG9OhESxwK0WjQxYOSfv40cU+T69w== + +"@rollup/rollup-win32-x64-msvc@4.16.4": + version "4.16.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.16.4.tgz#c09ad9a132ccb5a67c4f211d909323ab1294f95f" + integrity sha512-YunpoOAyGLDseanENHmbFvQSfVL5BxW3k7hhy0eN4rb3gS/ct75dVD0EXOWIqFT/nE8XYW6LP6vz6ctKRi0k9A== + "@rushstack/eslint-patch@^1.3.3": version "1.7.2" resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.7.2.tgz#2d4260033e199b3032a08b41348ac10de21c47e9" @@ -576,6 +656,11 @@ dependencies: tslib "^2.4.0" +"@types/estree@1.0.5": + version "1.0.5" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4" + integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== + "@types/json-schema@^7.0.12", "@types/json-schema@^7.0.9": version "7.0.15" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" @@ -928,6 +1013,19 @@ ansi-styles@^6.1.0: resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== +any-promise@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" + integrity sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A== + +anymatch@~3.1.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + argparse@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" @@ -1053,6 +1151,11 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== +binary-extensions@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522" + integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw== + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -1068,7 +1171,7 @@ brace-expansion@^2.0.1: dependencies: balanced-match "^1.0.0" -braces@^3.0.2: +braces@^3.0.2, braces@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== @@ -1090,6 +1193,13 @@ builtin-modules@^3.3.0: resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.3.0.tgz#cae62812b89801e9656336e46223e030386be7b6" integrity sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw== +bundle-require@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/bundle-require/-/bundle-require-4.0.3.tgz#916115a75d2d038a6fd0e08669887aba30128561" + integrity sha512-2iscZ3fcthP2vka4Y7j277YJevwmsby/FpFDwjgw34Nl7dtCpt7zz/4TexmHMzY6KZEih7En9ImlbbgUNNQGtA== + dependencies: + load-tsconfig "^0.2.3" + busboy@1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/busboy/-/busboy-1.6.0.tgz#966ea36a9502e43cdb9146962523b92f531f6893" @@ -1097,6 +1207,11 @@ busboy@1.6.0: dependencies: streamsearch "^1.1.0" +cac@^6.7.12: + version "6.7.14" + resolved "https://registry.yarnpkg.com/cac/-/cac-6.7.14.tgz#804e1e6f506ee363cb0e3ccbb09cad5dd9870959" + integrity sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ== + call-bind@^1.0.0, call-bind@^1.0.2, call-bind@^1.0.4, call-bind@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.5.tgz#6fa2b7845ce0ea49bf4d8b9ef64727a2c2e2e513" @@ -1133,6 +1248,21 @@ chalk@^4.0.0: ansi-styles "^4.1.0" supports-color "^7.1.0" +chokidar@^3.5.1: + version "3.6.0" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b" + integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + ci-info@^3.8.0: version "3.9.0" resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.9.0.tgz#4279a62028a7b1f262f3473fc9605f5e218c59b4" @@ -1174,6 +1304,11 @@ color-name@~1.1.4: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +commander@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" + integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== + concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" @@ -1184,7 +1319,7 @@ convert-source-map@^2.0.0: resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== -cross-spawn@^7.0.0, cross-spawn@^7.0.2: +cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== @@ -1406,7 +1541,7 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" -esbuild@~0.19.10: +esbuild@^0.19.2, esbuild@~0.19.10: version "0.19.12" resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.19.12.tgz#dc82ee5dc79e82f5a5c3b4323a2a641827db3e04" integrity sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg== @@ -1744,6 +1879,21 @@ esutils@^2.0.2: resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== +execa@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" + fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" @@ -1841,7 +1991,7 @@ fs.realpath@^1.0.0: resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== -fsevents@~2.3.3: +fsevents@~2.3.2, fsevents@~2.3.3: version "2.3.3" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== @@ -1886,6 +2036,11 @@ get-stdin@^9.0.0: resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-9.0.0.tgz#3983ff82e03d56f1b2ea0d3e60325f39d703a575" integrity sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA== +get-stream@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + get-symbol-description@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" @@ -1906,7 +2061,7 @@ git-hooks-list@^3.0.0: resolved "https://registry.yarnpkg.com/git-hooks-list/-/git-hooks-list-3.1.0.tgz#386dc531dcc17474cf094743ff30987a3d3e70fc" integrity sha512-LF8VeHeR7v+wAbXqfgRlTSX/1BJR9Q1vEMR8JAz1cEg6GX07+zyj3sAdDvYjj/xnlIfVuGgj4qBei1K3hKH+PA== -glob-parent@^5.1.2: +glob-parent@^5.1.2, glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== @@ -1920,6 +2075,17 @@ glob-parent@^6.0.2: dependencies: is-glob "^4.0.3" +glob@^10.3.10: + version "10.3.12" + resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.12.tgz#3a65c363c2e9998d220338e88a5f6ac97302960b" + integrity sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg== + dependencies: + foreground-child "^3.1.0" + jackspeak "^2.3.6" + minimatch "^9.0.1" + minipass "^7.0.4" + path-scurry "^1.10.2" + glob@^10.3.7: version "10.3.10" resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.10.tgz#0351ebb809fd187fe421ab96af83d3a70715df4b" @@ -1962,7 +2128,7 @@ globalthis@^1.0.3: dependencies: define-properties "^1.1.3" -globby@^11.1.0: +globby@^11.0.3, globby@^11.1.0: version "11.1.0" resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== @@ -2053,6 +2219,11 @@ hosted-git-info@^2.1.4: resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + ignore@^5.0.5, ignore@^5.2.0, ignore@^5.2.4: version "5.3.0" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.0.tgz#67418ae40d34d6999c95ff56016759c718c82f78" @@ -2126,6 +2297,13 @@ is-bigint@^1.0.1: dependencies: has-bigints "^1.0.1" +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + is-boolean-object@^1.1.0: version "1.1.2" resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" @@ -2184,7 +2362,7 @@ is-generator-function@^1.0.10: dependencies: has-tostringtag "^1.0.0" -is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3: +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: version "4.0.3" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== @@ -2243,6 +2421,11 @@ is-shared-array-buffer@^1.0.2: dependencies: call-bind "^1.0.2" +is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== + is-string@^1.0.5, is-string@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" @@ -2305,7 +2488,7 @@ iterator.prototype@^1.1.2: reflect.getprototypeof "^1.0.4" set-function-name "^2.0.1" -jackspeak@^2.3.5: +jackspeak@^2.3.5, jackspeak@^2.3.6: version "2.3.6" resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-2.3.6.tgz#647ecc472238aee4b06ac0e461acc21a8c505ca8" integrity sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ== @@ -2319,6 +2502,11 @@ jju@~1.4.0: resolved "https://registry.yarnpkg.com/jju/-/jju-1.4.0.tgz#a3abe2718af241a2b2904f84a625970f389ae32a" integrity sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA== +joycon@^3.0.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/joycon/-/joycon-3.1.1.tgz#bce8596d6ae808f8b68168f5fc69280996894f03" + integrity sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw== + "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" @@ -2415,11 +2603,21 @@ levn@^0.4.1: prelude-ls "^1.2.1" type-check "~0.4.0" +lilconfig@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-3.1.1.tgz#9d8a246fa753106cfc205fd2d77042faca56e5e3" + integrity sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ== + lines-and-columns@^1.1.6: version "1.2.4" resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== +load-tsconfig@^0.2.3: + version "0.2.5" + resolved "https://registry.yarnpkg.com/load-tsconfig/-/load-tsconfig-0.2.5.tgz#453b8cd8961bfb912dea77eb6c168fe8cca3d3a1" + integrity sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg== + locate-path@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" @@ -2439,6 +2637,11 @@ lodash.merge@^4.6.2: resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== +lodash.sortby@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" + integrity sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA== + lodash@^4.17.21: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" @@ -2451,6 +2654,11 @@ loose-envify@^1.1.0, loose-envify@^1.4.0: dependencies: js-tokens "^3.0.0 || ^4.0.0" +lru-cache@^10.2.0: + version "10.2.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.2.1.tgz#e8d901141f22937968e45a6533d52824070151e4" + integrity sha512-tS24spDe/zXhWbNPErCHs/AGOzbKGHT+ybSBqmdLm8WZ1xXLWvH8Qn71QPAlqVhd0qUTWjy+Kl9JmISgDdEjsA== + lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" @@ -2470,6 +2678,11 @@ lru-cache@^6.0.0: resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.2.0.tgz#0bd445ca57363465900f4d1f9bd8db343a4d95c3" integrity sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q== +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + merge2@^1.3.0, merge2@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" @@ -2483,6 +2696,11 @@ micromatch@^4.0.4: braces "^3.0.2" picomatch "^2.3.1" +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + min-indent@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" @@ -2507,7 +2725,7 @@ minimist@^1.2.0, minimist@^1.2.6: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== -"minipass@^5.0.0 || ^6.0.2 || ^7.0.0": +"minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.0.4: version "7.0.4" resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.0.4.tgz#dbce03740f50a4786ba994c1fb908844d27b038c" integrity sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ== @@ -2522,6 +2740,15 @@ ms@^2.1.1: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== +mz@^2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" + integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q== + dependencies: + any-promise "^1.0.0" + object-assign "^4.0.1" + thenify-all "^1.0.0" + nanoid@^3.3.6: version "3.3.7" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8" @@ -2570,7 +2797,19 @@ normalize-package-data@^2.5.0: semver "2 || 3 || 4 || 5" validate-npm-package-license "^3.0.1" -object-assign@^4.1.1: +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +npm-run-path@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + +object-assign@^4.0.1, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== @@ -2647,6 +2886,13 @@ once@^1.3.0: dependencies: wrappy "1" +onetime@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + optionator@^0.9.3: version "0.9.3" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64" @@ -2719,7 +2965,7 @@ path-is-absolute@^1.0.0: resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== -path-key@^3.1.0: +path-key@^3.0.0, path-key@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== @@ -2737,6 +2983,14 @@ path-scurry@^1.10.1: lru-cache "^9.1.1 || ^10.0.0" minipass "^5.0.0 || ^6.0.2 || ^7.0.0" +path-scurry@^1.10.2: + version "1.10.2" + resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.10.2.tgz#8f6357eb1239d5fa1da8b9f70e9c080675458ba7" + integrity sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA== + dependencies: + lru-cache "^10.2.0" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + path-type@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" @@ -2747,16 +3001,29 @@ picocolors@^1.0.0: resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== -picomatch@^2.3.1: +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== +pirates@^4.0.1: + version "4.0.6" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9" + integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg== + pluralize@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-8.0.0.tgz#1a6fa16a38d12a1901e0320fa017051c539ce3b1" integrity sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA== +postcss-load-config@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-4.0.2.tgz#7159dcf626118d33e299f485d6afe4aff7c4a3e3" + integrity sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ== + dependencies: + lilconfig "^3.0.0" + yaml "^2.3.4" + postcss@8.4.31: version "8.4.31" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.31.tgz#92b451050a9f914da6755af352bdc0192508656d" @@ -2849,6 +3116,13 @@ read-pkg@^5.2.0: parse-json "^5.0.0" type-fest "^0.6.0" +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + reflect.getprototypeof@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/reflect.getprototypeof/-/reflect.getprototypeof-1.0.4.tgz#aaccbf41aca3821b87bb71d9dcbc7ad0ba50a3f3" @@ -2892,6 +3166,11 @@ resolve-from@^4.0.0: resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== +resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + resolve-pkg-maps@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz#616b3dc2c57056b5588c31cdf4b3d64db133720f" @@ -2942,6 +3221,31 @@ rimraf@^5.0.5: dependencies: glob "^10.3.7" +rollup@^4.0.2: + version "4.16.4" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.16.4.tgz#fe328eb41293f20c9593a095ec23bdc4b5d93317" + integrity sha512-kuaTJSUbz+Wsb2ATGvEknkI12XV40vIiHmLuFlejoo7HtDok/O5eDDD0UpCVY5bBX5U5RYo8wWP83H7ZsqVEnA== + dependencies: + "@types/estree" "1.0.5" + optionalDependencies: + "@rollup/rollup-android-arm-eabi" "4.16.4" + "@rollup/rollup-android-arm64" "4.16.4" + "@rollup/rollup-darwin-arm64" "4.16.4" + "@rollup/rollup-darwin-x64" "4.16.4" + "@rollup/rollup-linux-arm-gnueabihf" "4.16.4" + "@rollup/rollup-linux-arm-musleabihf" "4.16.4" + "@rollup/rollup-linux-arm64-gnu" "4.16.4" + "@rollup/rollup-linux-arm64-musl" "4.16.4" + "@rollup/rollup-linux-powerpc64le-gnu" "4.16.4" + "@rollup/rollup-linux-riscv64-gnu" "4.16.4" + "@rollup/rollup-linux-s390x-gnu" "4.16.4" + "@rollup/rollup-linux-x64-gnu" "4.16.4" + "@rollup/rollup-linux-x64-musl" "4.16.4" + "@rollup/rollup-win32-arm64-msvc" "4.16.4" + "@rollup/rollup-win32-ia32-msvc" "4.16.4" + "@rollup/rollup-win32-x64-msvc" "4.16.4" + fsevents "~2.3.2" + run-parallel@^1.1.9: version "1.2.0" resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" @@ -3033,6 +3337,11 @@ side-channel@^1.0.4: get-intrinsic "^1.0.2" object-inspect "^1.9.0" +signal-exit@^3.0.3: + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + signal-exit@^4.0.1: version "4.1.0" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" @@ -3071,6 +3380,13 @@ source-map-js@^1.0.2: resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== +source-map@0.8.0-beta.0: + version "0.8.0-beta.0" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.8.0-beta.0.tgz#d4c1bb42c3f7ee925f005927ba10709e0d1d1f11" + integrity sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA== + dependencies: + whatwg-url "^7.0.0" + spdx-correct@^3.0.0: version "3.2.0" resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.2.0.tgz#4f5ab0668f0059e34f9c00dce331784a12de4e9c" @@ -3103,6 +3419,7 @@ streamsearch@^1.1.0: integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== "string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0: + name string-width-cjs version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -3181,6 +3498,11 @@ strip-bom@^3.0.0: resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + strip-indent@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-3.0.0.tgz#c32e1cee940b6b3432c771bc2c54bcce73cd3001" @@ -3200,6 +3522,19 @@ styled-jsx@5.1.1: dependencies: client-only "0.0.1" +sucrase@^3.20.3: + version "3.35.0" + resolved "https://registry.yarnpkg.com/sucrase/-/sucrase-3.35.0.tgz#57f17a3d7e19b36d8995f06679d121be914ae263" + integrity sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA== + dependencies: + "@jridgewell/gen-mapping" "^0.3.2" + commander "^4.0.0" + glob "^10.3.10" + lines-and-columns "^1.1.6" + mz "^2.7.0" + pirates "^4.0.1" + ts-interface-checker "^0.1.9" + supports-color@^5.3.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" @@ -3237,6 +3572,20 @@ text-table@^0.2.0: resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== +thenify-all@^1.0.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" + integrity sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA== + dependencies: + thenify ">= 3.1.0 < 4" + +"thenify@>= 3.1.0 < 4": + version "3.3.1" + resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.1.tgz#8932e686a4066038a016dd9e2ca46add9838a95f" + integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw== + dependencies: + any-promise "^1.0.0" + to-fast-properties@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" @@ -3249,11 +3598,28 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" +tr46@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" + integrity sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA== + dependencies: + punycode "^2.1.0" + +tree-kill@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" + integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A== + ts-api-utils@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.0.3.tgz#f12c1c781d04427313dbac808f453f050e54a331" integrity sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg== +ts-interface-checker@^0.1.9: + version "0.1.13" + resolved "https://registry.yarnpkg.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz#784fd3d679722bc103b1b4b8030bcddb5db2a699" + integrity sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA== + tsconfig-paths@^3.15.0: version "3.15.0" resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz#5299ec605e55b1abb23ec939ef15edaf483070d4" @@ -3274,6 +3640,26 @@ tslib@^2.4.0, tslib@^2.6.2: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== +tsup@^8.0.2: + version "8.0.2" + resolved "https://registry.yarnpkg.com/tsup/-/tsup-8.0.2.tgz#c63192a08386515103e2c44ac5a23bdff75c5fa1" + integrity sha512-NY8xtQXdH7hDUAZwcQdY/Vzlw9johQsaqf7iwZ6g1DOUlFYQ5/AtVAjTvihhEyeRlGo4dLRVHtrRaL35M1daqQ== + dependencies: + bundle-require "^4.0.0" + cac "^6.7.12" + chokidar "^3.5.1" + debug "^4.3.1" + esbuild "^0.19.2" + execa "^5.0.0" + globby "^11.0.3" + joycon "^3.0.1" + postcss-load-config "^4.0.1" + resolve-from "^5.0.0" + rollup "^4.0.2" + source-map "0.8.0-beta.0" + sucrase "^3.20.3" + tree-kill "^1.2.2" + tsutils@^3.21.0: version "3.21.0" resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" @@ -3437,6 +3823,20 @@ validate-npm-package-license@^3.0.1: spdx-correct "^3.0.0" spdx-expression-parse "^3.0.0" +webidl-conversions@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" + integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== + +whatwg-url@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06" + integrity sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg== + dependencies: + lodash.sortby "^4.7.0" + tr46 "^1.0.1" + webidl-conversions "^4.0.2" + which-boxed-primitive@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" @@ -3527,6 +3927,11 @@ yallist@^4.0.0: resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== +yaml@^2.3.4: + version "2.4.1" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.4.1.tgz#2e57e0b5e995292c25c75d2658f0664765210eed" + integrity sha512-pIXzoImaqmfOrL7teGUBt/T7ZDnyeGBWyXQBvOVhLkWLN37GXv8NMLK406UY6dS51JfcQHsmcW5cJ441bHg6Lg== + yocto-queue@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" diff --git a/examples/with-rollup/packages/config-eslint/react-internal.js b/examples/with-rollup/packages/config-eslint/react-internal.js index 2041783d0f8d9..c3b62a5bc73c0 100644 --- a/examples/with-rollup/packages/config-eslint/react-internal.js +++ b/examples/with-rollup/packages/config-eslint/react-internal.js @@ -6,10 +6,6 @@ const project = resolve(process.cwd(), "tsconfig.json"); * This is a custom ESLint configuration for use with * internal (bundled by their consumer) libraries * that utilize React. - * - * This config extends the Vercel Engineering Style Guide. - * For more information, see https://github.com/vercel/style-guide - * */ /** @type {import("eslint").Linter.Config} */ diff --git a/examples/with-yarn/packages/eslint-config/react-internal.js b/examples/with-yarn/packages/eslint-config/react-internal.js index f56c9249e7729..0b53f12c987bf 100644 --- a/examples/with-yarn/packages/eslint-config/react-internal.js +++ b/examples/with-yarn/packages/eslint-config/react-internal.js @@ -6,10 +6,6 @@ const project = resolve(process.cwd(), "tsconfig.json"); * This is a custom ESLint configuration for use with * internal (bundled by their consumer) libraries * that utilize React. - * - * This config extends the Vercel Engineering Style Guide. - * For more information, see https://github.com/vercel/style-guide - * */ /** @type {import("eslint").Linter.Config} */ diff --git a/packages/create-turbo/package.json b/packages/create-turbo/package.json index 127843b05a897..e884257794932 100644 --- a/packages/create-turbo/package.json +++ b/packages/create-turbo/package.json @@ -1,6 +1,6 @@ { "name": "create-turbo", - "version": "1.13.3-canary.4", + "version": "1.13.4-canary.3", "description": "Create a new Turborepo", "homepage": "https://turbo.build/repo", "license": "MPL-2.0", diff --git a/packages/eslint-config-turbo/package.json b/packages/eslint-config-turbo/package.json index 71084aa01414a..df64d2d521ddd 100644 --- a/packages/eslint-config-turbo/package.json +++ b/packages/eslint-config-turbo/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-turbo", - "version": "1.13.3-canary.4", + "version": "1.13.4-canary.3", "description": "ESLint config for Turborepo", "repository": { "type": "git", diff --git a/packages/eslint-plugin-turbo/package.json b/packages/eslint-plugin-turbo/package.json index 25cb6b36fcdb1..2f91969c7e454 100644 --- a/packages/eslint-plugin-turbo/package.json +++ b/packages/eslint-plugin-turbo/package.json @@ -1,6 +1,6 @@ { "name": "eslint-plugin-turbo", - "version": "1.13.3-canary.4", + "version": "1.13.4-canary.3", "description": "ESLint plugin for Turborepo", "keywords": [ "turbo", diff --git a/packages/turbo-codemod/package.json b/packages/turbo-codemod/package.json index 7f65dc67d4a95..93aba897ef858 100644 --- a/packages/turbo-codemod/package.json +++ b/packages/turbo-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@turbo/codemod", - "version": "1.13.3-canary.4", + "version": "1.13.4-canary.3", "description": "Provides Codemod transformations to help upgrade your Turborepo codebase when a feature is deprecated.", "homepage": "https://turbo.build/repo", "license": "MPL-2.0", diff --git a/packages/turbo-gen/package.json b/packages/turbo-gen/package.json index 1de2ede18bb5e..c889dcf4059e1 100644 --- a/packages/turbo-gen/package.json +++ b/packages/turbo-gen/package.json @@ -1,6 +1,6 @@ { "name": "@turbo/gen", - "version": "1.13.3-canary.4", + "version": "1.13.4-canary.3", "description": "Extend a Turborepo", "homepage": "https://turbo.build/repo", "license": "MPL-2.0", diff --git a/packages/turbo-gen/src/templates/simple-js/package.json b/packages/turbo-gen/src/templates/simple-js/package.json new file mode 100644 index 0000000000000..5bbefffbabee3 --- /dev/null +++ b/packages/turbo-gen/src/templates/simple-js/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/packages/turbo-gen/src/templates/simple-ts/package.json b/packages/turbo-gen/src/templates/simple-ts/package.json new file mode 100644 index 0000000000000..5bbefffbabee3 --- /dev/null +++ b/packages/turbo-gen/src/templates/simple-ts/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/packages/turbo-ignore/package.json b/packages/turbo-ignore/package.json index 79f32ba327e64..735781992cf4e 100644 --- a/packages/turbo-ignore/package.json +++ b/packages/turbo-ignore/package.json @@ -1,6 +1,6 @@ { "name": "turbo-ignore", - "version": "1.13.3-canary.4", + "version": "1.13.4-canary.3", "description": "", "homepage": "https://turbo.build/repo", "keywords": [], diff --git a/packages/turbo-repository/turbo.json b/packages/turbo-repository/turbo.json index 812458b1399d3..db457aba7bbee 100644 --- a/packages/turbo-repository/turbo.json +++ b/packages/turbo-repository/turbo.json @@ -6,7 +6,7 @@ "pipeline": { "build": { "dependsOn": [ - "cli#build" + "cli#rust-src" ] }, "test": { diff --git a/packages/turbo-telemetry/src/config.test.ts b/packages/turbo-telemetry/src/config.test.ts index 3b9ab3c3b2c9d..2410ff83e758f 100644 --- a/packages/turbo-telemetry/src/config.test.ts +++ b/packages/turbo-telemetry/src/config.test.ts @@ -240,7 +240,7 @@ describe("TelemetryConfig", () => { telemetry_enabled: true, telemetry_id: "123456", telemetry_salt: "private-salt", - telemetry_alerted: new Date(), + telemetry_alerted: new Date().toISOString(), }, }); @@ -389,7 +389,7 @@ describe("TelemetryConfig", () => { telemetry_enabled: true, telemetry_id: "123456", telemetry_salt: "private-salt", - telemetry_alerted: new Date(), + telemetry_alerted: new Date().toISOString(), }, }); @@ -401,11 +401,6 @@ describe("TelemetryConfig", () => { test("should set telemetry_alerted to current date and write the config if telemetry_alerted is undefined", (t) => { const mockWriteFileSync = mock.fn(); t.mock.method(fs, "writeFileSync", mockWriteFileSync); - mock.timers.enable({ - apis: ["Date"], - now: new Date("2021-01-01T00:00:00.000Z"), - }); - const result = telemetryConfig.alertShown(); assert.equal(result, true); diff --git a/packages/turbo-telemetry/src/config.ts b/packages/turbo-telemetry/src/config.ts index ab270326121c4..ea78c3fca78f2 100644 --- a/packages/turbo-telemetry/src/config.ts +++ b/packages/turbo-telemetry/src/config.ts @@ -14,7 +14,7 @@ const ConfigSchema = z.object({ telemetry_enabled: z.boolean(), telemetry_id: z.string(), telemetry_salt: z.string(), - telemetry_alerted: z.date().optional(), + telemetry_alerted: z.string().optional(), }); type Config = z.infer; @@ -188,7 +188,7 @@ export class TelemetryConfig { return true; } - this.config.telemetry_alerted = new Date(); + this.config.telemetry_alerted = new Date().toISOString(); this.tryWrite(); return true; } diff --git a/packages/turbo-types/package.json b/packages/turbo-types/package.json index 02b44f772148e..7dd565271efb6 100644 --- a/packages/turbo-types/package.json +++ b/packages/turbo-types/package.json @@ -1,6 +1,6 @@ { "name": "@turbo/types", - "version": "1.13.3-canary.4", + "version": "1.13.4-canary.3", "description": "Turborepo types", "homepage": "https://turbo.build/repo", "license": "MPL-2.0", diff --git a/packages/turbo-vsc/src/extension.ts b/packages/turbo-vsc/src/extension.ts index 3e2875fe4fe95..2d407a7c3b1bc 100644 --- a/packages/turbo-vsc/src/extension.ts +++ b/packages/turbo-vsc/src/extension.ts @@ -42,6 +42,8 @@ const decoration = window.createTextEditorDecorationType({ color: "#04f1f9", // something like cyan }); +const logs = window.createOutputChannel("Turborepo Extension"); + function rainbowRgb(i: number) { const f = 0.5; const r = Math.sin(f * i + (4.0 * Math.PI) / 3.0) * 127.0 + 128.0; @@ -71,21 +73,27 @@ export function activate(context: ExtensionContext) { let turboPath: string | undefined = turboSettings.get("path"); const useLocalTurbo: boolean = turboSettings.get("useLocalTurbo") ?? false; + logs.appendLine("starting the turbo extension"); + if (turboPath && !fs.existsSync(turboPath)) { - window.showErrorMessage( - `turbo does not exist at path \`${turboPath}\`, attempting to locate it` + logs.appendLine( + `manually specified turbo does not exist at path \`${turboPath}\`, attempting to locate it` ); turboPath = undefined; } try { if (turboPath == null) { - turboPath = cp.execSync( - // attempt to source two well known version managers - // as well as adding the bun global bin to the path - 'sh -c \'source "$HOME/.nvm/nvm.sh" > /dev/null 2>&1; source "$HOME/.asdf/asdf.sh" > /dev/null 2>&1; export PATH="$HOME/.bun/bin:$PATH"; which turbo\'', - options - ); + logs.appendLine("attempting to find global turbo"); + turboPath = cp + .execSync( + // attempt to source two well known version managers + // as well as adding the bun global bin to the path + 'bash -c \'source "$HOME/.nvm/nvm.sh" > /dev/null 2>&1; source "$HOME/.asdf/asdf.sh" > /dev/null 2>&1; eval "$(brew shellenv)" > /dev/null 2>&1; export PATH="$HOME/.bun/bin:$PATH"; which turbo\'', + options + ) + .trim(); + logs.appendLine(`set turbo path to ${turboPath}`); } } catch (e: any) { if ( @@ -94,13 +102,18 @@ export function activate(context: ExtensionContext) { e.message.includes("which: no turbo in") ) { // attempt to find local turbo instead + logs.appendLine("prompting global turbo"); promptGlobalTurbo(useLocalTurbo); turboPath = findLocalTurbo(); } else { - window.showErrorMessage(e.message); + logs.appendLine(`unable to find turbo: ${e.message}`); } } + if (turboPath) { + logs.appendLine(`using turbo at path ${turboPath}`); + } + context.subscriptions.push( commands.registerCommand("turbo.daemon.start", () => { cp.exec(`${turboPath} daemon start`, options, (err) => { @@ -108,7 +121,7 @@ export function activate(context: ExtensionContext) { if (err.message.includes("command not found")) { promptGlobalTurbo(useLocalTurbo); } else { - window.showErrorMessage(JSON.stringify(err)); + logs.appendLine(`unable to start turbo: ${err.message}`); } } else { updateStatusBarItem(true); @@ -125,7 +138,7 @@ export function activate(context: ExtensionContext) { if (err.message.includes("command not found")) { promptGlobalTurbo(useLocalTurbo); } else { - window.showErrorMessage(err.message); + logs.appendLine(`unable to stop turbo: ${err.message}`); } } else { updateStatusBarItem(false); @@ -142,7 +155,7 @@ export function activate(context: ExtensionContext) { if (err.message.includes("command not found")) { promptGlobalTurbo(useLocalTurbo); } else { - window.showErrorMessage(err.message); + logs.appendLine(`unable to get turbo status: ${err.message}`); updateStatusBarItem(false); } } else { @@ -384,6 +397,7 @@ function findLocalTurbo(): string | undefined { const checks = [ () => { + logs.appendLine("attempting to find local turbo using npm"); const npmList = cp.execSync("npm ls turbo --json", options); const npmData = JSON.parse(npmList); @@ -402,14 +416,17 @@ function findLocalTurbo(): string | undefined { } }, () => { + logs.appendLine("attempting to find local turbo using yarn"); const turboBin = cp.execSync("yarn bin turbo", options); return turboBin.trim(); }, () => { + logs.appendLine("attempting to find local turbo using pnpm"); const binFolder = cp.execSync("pnpm bin", options).trim(); return path.join(binFolder, "turbo"); }, () => { + logs.appendLine("attempting to find local turbo using bun"); const binFolder = cp.execSync("bun pm bin", options).trim(); return path.join(binFolder, "turbo"); }, @@ -417,8 +434,9 @@ function findLocalTurbo(): string | undefined { for (const potentialPath of checks) { try { - const potential = potentialPath(); + const potential = potentialPath()?.trim(); if (potential && fs.existsSync(potential)) { + logs.appendLine(`found local turbo at ${potential}`); return potential; } } catch (e) { diff --git a/packages/turbo-workspaces/package.json b/packages/turbo-workspaces/package.json index 0fed445b708e9..9d22992ab2cff 100644 --- a/packages/turbo-workspaces/package.json +++ b/packages/turbo-workspaces/package.json @@ -1,6 +1,6 @@ { "name": "@turbo/workspaces", - "version": "1.13.3-canary.4", + "version": "1.13.4-canary.3", "description": "Tools for working with package managers", "homepage": "https://turbo.build/repo", "license": "MPL-2.0", diff --git a/packages/turbo/package.json b/packages/turbo/package.json index 2f9c66aaea74d..e94c50b19dced 100644 --- a/packages/turbo/package.json +++ b/packages/turbo/package.json @@ -1,6 +1,6 @@ { "name": "turbo", - "version": "1.13.3-canary.4", + "version": "1.13.4-canary.3", "description": "Turborepo is a high-performance build system for JavaScript and TypeScript codebases.", "repository": "https://github.com/vercel/turbo", "bugs": "https://github.com/vercel/turbo/issues", @@ -17,11 +17,11 @@ "bin" ], "optionalDependencies": { - "turbo-darwin-64": "1.13.3-canary.4", - "turbo-darwin-arm64": "1.13.3-canary.4", - "turbo-linux-64": "1.13.3-canary.4", - "turbo-linux-arm64": "1.13.3-canary.4", - "turbo-windows-64": "1.13.3-canary.4", - "turbo-windows-arm64": "1.13.3-canary.4" + "turbo-darwin-64": "1.13.4-canary.3", + "turbo-darwin-arm64": "1.13.4-canary.3", + "turbo-linux-64": "1.13.4-canary.3", + "turbo-linux-arm64": "1.13.4-canary.3", + "turbo-windows-64": "1.13.4-canary.3", + "turbo-windows-arm64": "1.13.4-canary.3" } } diff --git a/release.md b/release.md index bf45e2291e49e..0c4415a548f3b 100644 --- a/release.md +++ b/release.md @@ -46,7 +46,7 @@ You need to run `git push --follow-tags` to finish the release. ## Release Turborepo -1. Create a release by triggering the [1. Turborepo Release][1] workflow +1. Create a release by triggering the [Turborepo Release][1] workflow - Specify the semver increment using the SemVer Increment field (start with `prerelease`) - Check the "Dry Run" box to run the full release workflow without publishing any packages. @@ -60,6 +60,15 @@ You need to run `git push --follow-tags` to finish the release. - Github Release Notes are published automatically using the config from [`turborepo-release.yml`][2], triggered by the [`turbo-orchestrator`][3] bot. +## Release `@turbo/repository` + +1. Run [`bump-version.sh`][4] to update the versions of the packages. Merge in the changes to `main`. + +2. Create a release by triggering the [Turborepo Library Release][5] workflow. + - Check the "Dry Run" box to run the full release workflow without publishing any packages. + [1]: https://github.com/vercel/turbo/actions/workflows/turborepo-release.yml [2]: https://github.com/vercel/turbo/blob/main/.github/turborepo-release.yml [3]: https://github.com/apps/turbo-orchestrator +[4]: https://github.com/vercel/turbo/blob/main/packages/turbo-repository/scripts/bump-version.sh +[5]: https://github.com/vercel/turbo/actions/workflows/turborepo-library-release.yml diff --git a/turborepo-tests/integration/tests/lockfile-aware-caching/new-package.t b/turborepo-tests/integration/tests/lockfile-aware-caching/new-package.t new file mode 100644 index 0000000000000..f23135e461c62 --- /dev/null +++ b/turborepo-tests/integration/tests/lockfile-aware-caching/new-package.t @@ -0,0 +1,22 @@ +Setup + $ . ${TESTDIR}/../../../helpers/setup.sh + $ . ${TESTDIR}/setup.sh $(pwd) pnpm + +Add new package with an external dependency + $ mkdir -p apps/c + $ echo '{"name":"c", "dependencies": {"has-symbols": "^1.0.3"}}' > apps/c/package.json + +Update lockfile + $ pnpm i --frozen-lockfile=false > /dev/null + +Now build and verify that only the new package is in scope +Note that we need --skip-infer because we've now installed a local +turbo in this repo +Note that we need to disable path conversion because on windows, git bash considers +'//' to be an escape sequence translating to '/'. + $ MSYS_NO_PATHCONV=1 ${TURBO} --skip-infer build -F '[HEAD]' -F '!//' --dry=json | jq '.packages' + [ + "c" + ] + + diff --git a/version.txt b/version.txt index 37b902e1cddc0..3e66edcf50fc5 100644 --- a/version.txt +++ b/version.txt @@ -1,2 +1,2 @@ -1.13.3-canary.4 +1.13.4-canary.3 canary