Skip to content

Conversation

@anonrig
Copy link

@anonrig anonrig commented Dec 8, 2025

Improves performance of bundler by 2% on large projects

  📊 Benchmark Results

  | Metric      | Baseline (O(n²)) | Optimized (Hash Set) | Improvement    |
  |-------------|------------------|----------------------|----------------|
  | Best Time   | 60,969ms         | 59,632ms             | 1,337ms faster |
  | Improvement | -                | -                    | 2.19% faster   |
  | Run 1       | 61,032ms         | 60,188ms             | 844ms (1.4%)   |
  | Run 2       | 60,969ms         | 59,632ms             | 1,337ms (2.2%) |
  | Run 3       | 60,969ms         | 59,777ms             | 1,192ms (2.0%) |

  Test scenario: 500 files, 30,504 total exports, deep re-export chains

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 8, 2025

Walkthrough

Adds a module-loader benchmark script, simplifies base64 leftover checks to direct equality, implements a hybrid cycle-detection fast path and hash-set path in the bundler linker, and adds tests exercising several bundler cycle-detection scenarios.

Changes

Cohort / File(s) Summary
Benchmark additions
bench/module-loader/run-benchmark.sh
New shell benchmark script that prints headers, runs the module-loader binary three times, measures elapsed time with millisecond precision, tracks the best successful run, reports failures (exit code and captured output), prints the best time, and searches output for the "Loaded" string.
Base64 validity checks
src/base64/base64.zig
Replaced modulo-based leftover checks in Base64Decoder.calcSizeUpperBound with direct equality comparisons: padding case from leftover % 4 != 0leftover != 0; non-padding case from leftover % 4 == 1leftover == 1. No observable behavioral change.
Bundler cycle detection
src/bundler/LinkerContext.zig
Introduces a hybrid cycle-detection path in matchImportWithExport: a small-size O(n) scan over a cycle_slice for few trackers, and a large-size path using a hash set (cycle_set) with a new ImportTrackerHashCtx for O(1) lookups; populates and manages the set alongside existing logic.
Cycle detection tests
test/bundler/bundler_cycle_detection.test.ts
New test suite covering shallow and deep re-export cycles, a deep non-cyclic import chain (validating stdout "42"), and cross-file cycles; asserts expected bundle errors per entry.

Possibly related PRs

Pre-merge checks

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Description check ⚠️ Warning The description is incomplete. It provides benchmark results but does not follow the template structure with required sections 'What does this PR do?' and 'How did you verify your code works?' Structure the description according to the template: add 'What does this PR do?' section explaining the optimization approach, and 'How did you verify your code works?' section detailing verification methods.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title 'optimize bundler cycle detection' directly and concisely summarizes the main change: a performance optimization to the bundler's cycle detection mechanism, which is the focus of the PR.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 4980736 and 8c50565.

📒 Files selected for processing (4)
  • bench/module-loader/run-benchmark.sh (1 hunks)
  • src/base64/base64.zig (1 hunks)
  • src/bundler/LinkerContext.zig (4 hunks)
  • test/bundler/bundler_cycle_detection.test.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
test/**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/writing-tests.mdc)

test/**/*.{js,ts,jsx,tsx}: Write tests as JavaScript and TypeScript files using Jest-style APIs (test, describe, expect) and import from bun:test
Use test.each and data-driven tests to reduce boilerplate when testing multiple similar cases

Files:

  • test/bundler/bundler_cycle_detection.test.ts
test/**/*.test.{ts,js,jsx,tsx,mjs,cjs}

📄 CodeRabbit inference engine (test/CLAUDE.md)

test/**/*.test.{ts,js,jsx,tsx,mjs,cjs}: Use bun:test with files that end in *.test.{ts,js,jsx,tsx,mjs,cjs}
Do not write flaky tests. Never wait for time to pass in tests; always wait for the condition to be met instead of using an arbitrary amount of time
Never use hardcoded port numbers in tests. Always use port: 0 to get a random port
Prefer concurrent tests over sequential tests using test.concurrent or describe.concurrent when multiple tests spawn processes or write files, unless it's very difficult to make them concurrent
When spawning Bun processes in tests, use bunExe and bunEnv from harness to ensure the same build of Bun is used and debug logging is silenced
Use -e flag for single-file tests when spawning Bun processes
Use tempDir() from harness to create temporary directories with files for multi-file tests instead of creating files manually
Prefer async/await over callbacks in tests
When callbacks must be used and it's just a single callback, use Promise.withResolvers to create a promise that can be resolved or rejected from a callback
Do not set a timeout on tests. Bun already has timeouts
Use Buffer.alloc(count, fill).toString() instead of 'A'.repeat(count) to create repetitive strings in tests, as ''.repeat is very slow in debug JavaScriptCore builds
Use describe blocks for grouping related tests
Always use await using or using to ensure proper resource cleanup in tests for APIs like Bun.listen, Bun.connect, Bun.spawn, Bun.serve, etc
Always check exit codes and test error scenarios in error tests
Use describe.each() for parameterized tests
Use toMatchSnapshot() for snapshot testing
Use beforeAll(), afterEach(), beforeEach() for setup/teardown in tests
Track resources (servers, clients) in arrays for cleanup in afterEach()

Files:

  • test/bundler/bundler_cycle_detection.test.ts
test/**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

test/**/*.test.{ts,tsx}: For single-file tests in Bun test suite, prefer using -e flag over tempDir
For multi-file tests in Bun test suite, prefer using tempDir and Bun.spawn
Always use port: 0 when spawning servers in tests - do not hardcode ports or use custom random port functions
Use normalizeBunSnapshot to normalize snapshot output in tests instead of manual output comparison
Never write tests that check for no 'panic', 'uncaught exception', or similar strings in test output - that is not a valid test
Use tempDir from harness to create temporary directories in tests - do not use tmpdirSync or fs.mkdtempSync
In tests, call expect(stdout).toBe(...) before expect(exitCode).toBe(0) when spawning processes for more useful error messages on failure
Do not write flaky tests - do not use setTimeout in tests; instead await the condition to be met since you're testing the CONDITION, not TIME PASSING
Verify your test fails with USE_SYSTEM_BUN=1 bun test <file> and passes with bun bd test <file> - tests are not valid if they pass with USE_SYSTEM_BUN=1
Avoid shell commands in tests - do not use find or grep; use Bun's Glob and built-in tools instead
Test files must end in .test.ts or .test.tsx and be created in the appropriate test folder structure

Files:

  • test/bundler/bundler_cycle_detection.test.ts
src/**/*.{cpp,zig}

📄 CodeRabbit inference engine (.cursor/rules/building-bun.mdc)

src/**/*.{cpp,zig}: Use bun bd or bun run build:debug to build debug versions for C++ and Zig source files; creates debug build at ./build/debug/bun-debug
Run tests using bun bd test <test-file> with the debug build; never use bun test directly as it will not include your changes
Execute files using bun bd <file> <...args>; never use bun <file> directly as it will not include your changes
Enable debug logs for specific scopes using BUN_DEBUG_$(SCOPE)=1 environment variable
Code generation happens automatically as part of the build process; no manual code generation commands are required

Files:

  • src/bundler/LinkerContext.zig
  • src/base64/base64.zig
src/**/*.zig

📄 CodeRabbit inference engine (.cursor/rules/building-bun.mdc)

Use bun.Output.scoped(.${SCOPE}, .hidden) for creating debug logs in Zig code

Implement core functionality in Zig, typically in its own directory in src/

src/**/*.zig: Private fields in Zig are fully supported using the # prefix: struct { #foo: u32 };
Use decl literals in Zig for declaration initialization: const decl: Decl = .{ .binding = 0, .value = 0 };
Prefer @import at the bottom of the file (auto formatter will move them automatically)

Be careful with memory management in Zig code - use defer for cleanup with allocators

Files:

  • src/bundler/LinkerContext.zig
  • src/base64/base64.zig
**/*.zig

📄 CodeRabbit inference engine (.cursor/rules/zig-javascriptcore-classes.mdc)

**/*.zig: Expose generated bindings in Zig structs using pub const js = JSC.Codegen.JS<ClassName> with trait conversion methods: toJS, fromJS, and fromJSDirect
Use consistent parameter name globalObject instead of ctx in Zig constructor and method implementations
Use bun.JSError!JSValue return type for Zig methods and constructors to enable proper error handling and exception propagation
Implement resource cleanup using deinit() method that releases resources, followed by finalize() called by the GC that invokes deinit() and frees the pointer
Use JSC.markBinding(@src()) in finalize methods for debugging purposes before calling deinit()
For methods returning cached properties in Zig, declare external C++ functions using extern fn and callconv(JSC.conv) calling convention
Implement getter functions with naming pattern get<PropertyName> in Zig that accept this and globalObject parameters and return JSC.JSValue
Access JavaScript CallFrame arguments using callFrame.argument(i), check argument count with callFrame.argumentCount(), and get this with callFrame.thisValue()
For reference-counted objects, use .deref() in finalize instead of destroy() to release references to other JS objects

Files:

  • src/bundler/LinkerContext.zig
  • src/base64/base64.zig
🧠 Learnings (19)
📓 Common learnings
Learnt from: CR
Repo: oven-sh/bun PR: 0
File: .cursor/rules/dev-server-tests.mdc:0-0
Timestamp: 2025-11-24T18:35:08.612Z
Learning: Applies to test/bake/dev/bundle.test.ts : Organize bundle tests in bundle.test.ts for tests concerning bundling bugs that only occur in DevServer
Learnt from: CR
Repo: oven-sh/bun PR: 0
File: test/CLAUDE.md:0-0
Timestamp: 2025-11-24T18:37:30.259Z
Learning: Unit tests for specific features are organized by module (e.g., `/test/js/bun/`, `/test/js/node/`)
Learnt from: CR
Repo: oven-sh/bun PR: 0
File: src/bun.js/bindings/v8/CLAUDE.md:0-0
Timestamp: 2025-11-24T18:36:59.706Z
Learning: Ensure V8 API tests compare identical C++ code output between Node.js and Bun through the test suite validation process
Learnt from: CR
Repo: oven-sh/bun PR: 0
File: .cursor/rules/registering-bun-modules.mdc:0-0
Timestamp: 2025-11-24T18:35:39.205Z
Learning: Add tests for new Bun runtime functionality
Learnt from: CR
Repo: oven-sh/bun PR: 0
File: src/bun.js/bindings/v8/CLAUDE.md:0-0
Timestamp: 2025-11-24T18:36:59.706Z
Learning: Applies to src/bun.js/bindings/v8/test/v8/v8.test.ts : Add corresponding test cases to test/v8/v8.test.ts using checkSameOutput() function to compare Node.js and Bun output
Learnt from: CR
Repo: oven-sh/bun PR: 0
File: src/js/CLAUDE.md:0-0
Timestamp: 2025-11-24T18:37:11.466Z
Learning: Write JS builtins for Bun's Node.js compatibility and APIs, and run `bun bd` after changes
Learnt from: CR
Repo: oven-sh/bun PR: 0
File: .cursor/rules/dev-server-tests.mdc:0-0
Timestamp: 2025-11-24T18:35:08.612Z
Learning: Applies to test/bake/dev/esm.test.ts : Organize ESM tests in esm.test.ts for tests about various ESM features in development mode
📚 Learning: 2025-11-24T18:35:08.612Z
Learnt from: CR
Repo: oven-sh/bun PR: 0
File: .cursor/rules/dev-server-tests.mdc:0-0
Timestamp: 2025-11-24T18:35:08.612Z
Learning: Applies to test/bake/dev/bundle.test.ts : Organize bundle tests in bundle.test.ts for tests concerning bundling bugs that only occur in DevServer

Applied to files:

  • test/bundler/bundler_cycle_detection.test.ts
📚 Learning: 2025-11-24T18:35:08.612Z
Learnt from: CR
Repo: oven-sh/bun PR: 0
File: .cursor/rules/dev-server-tests.mdc:0-0
Timestamp: 2025-11-24T18:35:08.612Z
Learning: Applies to test/bake/dev/css.test.ts : Organize CSS tests in css.test.ts for tests concerning bundling bugs with CSS files

Applied to files:

  • test/bundler/bundler_cycle_detection.test.ts
📚 Learning: 2025-11-24T18:35:08.612Z
Learnt from: CR
Repo: oven-sh/bun PR: 0
File: .cursor/rules/dev-server-tests.mdc:0-0
Timestamp: 2025-11-24T18:35:08.612Z
Learning: Applies to test/bake/dev/esm.test.ts : Organize ESM tests in esm.test.ts for tests about various ESM features in development mode

Applied to files:

  • test/bundler/bundler_cycle_detection.test.ts
  • bench/module-loader/run-benchmark.sh
📚 Learning: 2025-11-24T18:35:08.612Z
Learnt from: CR
Repo: oven-sh/bun PR: 0
File: .cursor/rules/dev-server-tests.mdc:0-0
Timestamp: 2025-11-24T18:35:08.612Z
Learning: Applies to test/bake/dev/sourcemap.test.ts : Organize source-map tests in sourcemap.test.ts for tests verifying source-maps are correct

Applied to files:

  • test/bundler/bundler_cycle_detection.test.ts
📚 Learning: 2025-11-24T18:35:08.612Z
Learnt from: CR
Repo: oven-sh/bun PR: 0
File: .cursor/rules/dev-server-tests.mdc:0-0
Timestamp: 2025-11-24T18:35:08.612Z
Learning: Applies to test/bake/dev/ecosystem.test.ts : Organize ecosystem tests in ecosystem.test.ts for tests involving ensuring certain libraries are correct; prefer testing concrete bugs over testing entire packages

Applied to files:

  • test/bundler/bundler_cycle_detection.test.ts
📚 Learning: 2025-11-24T18:36:59.706Z
Learnt from: CR
Repo: oven-sh/bun PR: 0
File: src/bun.js/bindings/v8/CLAUDE.md:0-0
Timestamp: 2025-11-24T18:36:59.706Z
Learning: Applies to src/bun.js/bindings/v8/test/v8/v8.test.ts : Add corresponding test cases to test/v8/v8.test.ts using checkSameOutput() function to compare Node.js and Bun output

Applied to files:

  • test/bundler/bundler_cycle_detection.test.ts
📚 Learning: 2025-11-24T18:35:50.422Z
Learnt from: CR
Repo: oven-sh/bun PR: 0
File: .cursor/rules/writing-tests.mdc:0-0
Timestamp: 2025-11-24T18:35:50.422Z
Learning: Applies to test/**/*.{js,ts,jsx,tsx} : Write tests as JavaScript and TypeScript files using Jest-style APIs (`test`, `describe`, `expect`) and import from `bun:test`

Applied to files:

  • test/bundler/bundler_cycle_detection.test.ts
📚 Learning: 2025-11-24T18:35:08.612Z
Learnt from: CR
Repo: oven-sh/bun PR: 0
File: .cursor/rules/dev-server-tests.mdc:0-0
Timestamp: 2025-11-24T18:35:08.612Z
Learning: Applies to test/bake/**/*.test.ts : Specify expected bundling errors via the `errors` option when a client is expected to encounter an error; by default, a client opening a page to an error fails the test

Applied to files:

  • test/bundler/bundler_cycle_detection.test.ts
📚 Learning: 2025-12-02T05:59:51.485Z
Learnt from: CR
Repo: oven-sh/bun PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-02T05:59:51.485Z
Learning: Applies to test/**/*.test.{ts,tsx} : For multi-file tests in Bun test suite, prefer using `tempDir` and `Bun.spawn`

Applied to files:

  • test/bundler/bundler_cycle_detection.test.ts
📚 Learning: 2025-11-24T18:35:50.422Z
Learnt from: CR
Repo: oven-sh/bun PR: 0
File: .cursor/rules/writing-tests.mdc:0-0
Timestamp: 2025-11-24T18:35:50.422Z
Learning: See `test/harness.ts` for common test utilities and helpers

Applied to files:

  • test/bundler/bundler_cycle_detection.test.ts
📚 Learning: 2025-11-24T18:37:30.259Z
Learnt from: CR
Repo: oven-sh/bun PR: 0
File: test/CLAUDE.md:0-0
Timestamp: 2025-11-24T18:37:30.259Z
Learning: Unit tests for specific features are organized by module (e.g., `/test/js/bun/`, `/test/js/node/`)

Applied to files:

  • test/bundler/bundler_cycle_detection.test.ts
📚 Learning: 2025-10-19T02:44:46.354Z
Learnt from: theshadow27
Repo: oven-sh/bun PR: 23798
File: packages/bun-otel/context-propagation.test.ts:1-1
Timestamp: 2025-10-19T02:44:46.354Z
Learning: In the Bun repository, standalone packages under packages/ (e.g., bun-vscode, bun-inspector-protocol, bun-plugin-yaml, bun-plugin-svelte, bun-debug-adapter-protocol, bun-otel) co-locate their tests with package source code using *.test.ts files. This follows standard npm/monorepo patterns. The test/ directory hierarchy (test/js/bun/, test/cli/, test/js/node/) is reserved for testing Bun's core runtime APIs and built-in functionality, not standalone packages.

Applied to files:

  • test/bundler/bundler_cycle_detection.test.ts
📚 Learning: 2025-11-24T18:37:30.259Z
Learnt from: CR
Repo: oven-sh/bun PR: 0
File: test/CLAUDE.md:0-0
Timestamp: 2025-11-24T18:37:30.259Z
Learning: Applies to test/**/*.test.{ts,js,jsx,tsx,mjs,cjs} : When spawning Bun processes in tests, use `bunExe` and `bunEnv` from `harness` to ensure the same build of Bun is used and debug logging is silenced

Applied to files:

  • test/bundler/bundler_cycle_detection.test.ts
📚 Learning: 2025-09-06T03:37:41.154Z
Learnt from: taylordotfish
Repo: oven-sh/bun PR: 22229
File: src/bundler/LinkerGraph.zig:0-0
Timestamp: 2025-09-06T03:37:41.154Z
Learning: In Bun's codebase, when checking import record source indices in src/bundler/LinkerGraph.zig, prefer using `if (import_index >= self.import_records.len)` bounds checking over `isValid()` checks, as the bounds check is more robust and `isValid()` is a strict subset of this condition.

Applied to files:

  • src/bundler/LinkerContext.zig
  • src/base64/base64.zig
📚 Learning: 2025-09-07T14:00:36.526Z
Learnt from: RiskyMH
Repo: oven-sh/bun PR: 22258
File: src/bun.js/test/jest.zig:63-86
Timestamp: 2025-09-07T14:00:36.526Z
Learning: In Bun's Zig codebase, the established pattern for HashMap hash functions is to truncate hash values to u32, even when the underlying hash computation produces u64. This is seen throughout the codebase, such as in src/css/rules/rules.zig where u64 hashes are stored but truncated to u32 in HashMap contexts. When implementing HashContext for HashMapUnmanaged, the hash function should return u32 to match this pattern.

Applied to files:

  • src/bundler/LinkerContext.zig
📚 Learning: 2025-12-02T05:59:51.485Z
Learnt from: CR
Repo: oven-sh/bun PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-02T05:59:51.485Z
Learning: Applies to src/bun.js/bindings/**/*.cpp : Cache structures in ZigGlobalObject for C++ JavaScript classes

Applied to files:

  • src/bundler/LinkerContext.zig
📚 Learning: 2025-11-10T00:57:09.173Z
Learnt from: franciscop
Repo: oven-sh/bun PR: 24514
File: src/bun.js/api/crypto/PasswordObject.zig:86-101
Timestamp: 2025-11-10T00:57:09.173Z
Learning: In Bun's Zig codebase (PasswordObject.zig), when validating the parallelism parameter for Argon2, the upper limit is set to 65535 (2^16 - 1) rather than using `std.math.maxInt(u24)` because the latter triggers Zig's truncation limit checks. The value 65535 is a practical upper bound that avoids compiler issues while being sufficient for thread parallelism use cases.

Applied to files:

  • src/base64/base64.zig
📚 Learning: 2025-10-24T10:43:09.398Z
Learnt from: fmguerreiro
Repo: oven-sh/bun PR: 23774
File: src/install/PackageManager/updatePackageJSONAndInstall.zig:548-548
Timestamp: 2025-10-24T10:43:09.398Z
Learning: In Bun's Zig codebase, the `as(usize, intCast(...))` cast pattern triggers a Zig compiler bug that causes compilation to hang indefinitely when used in complex control flow contexts (loops + short-circuit operators + optional unwrapping). Avoid this pattern and use simpler alternatives like just `intCast(...)` if type casting is necessary.

Applied to files:

  • src/base64/base64.zig
🧬 Code graph analysis (1)
test/bundler/bundler_cycle_detection.test.ts (1)
test/bundler/expectBundled.ts (1)
  • itBundled (1758-1792)
🔇 Additional comments (6)
src/base64/base64.zig (1)

270-280: LGTM! Redundant modulo operations removed.

Since leftover = source_len % 4 is already in range [0, 3], the additional % 4 operations were redundant. The simplified equality checks are functionally equivalent and slightly more efficient.

src/bundler/LinkerContext.zig (2)

1839-1874: LGTM! Hybrid approach balances small-cycle efficiency with large-cycle scalability.

The optimization correctly:

  • Uses O(n) array scan for small cycles (< 8 elements) avoiding hash map overhead
  • Lazily initializes the hash set only when needed
  • Properly defers cleanup of the hash set

1882-1887: Verify: Tracker is appended to array but also added to hash set.

The tracker is appended to cycle_detector (line 1882) regardless of whether the hash path is active. Then if cycle_set.count() > 0, it's also added to the hash set (lines 1885-1887). This is correct behavior - the array is needed for re_exports dependencies, and the hash set is for O(1) cycle detection.

test/bundler/bundler_cycle_detection.test.ts (2)

3-130: LGTM! Comprehensive test coverage for cycle detection optimization.

The test suite effectively covers:

  • ShallowCycleDetection (4 depth): Exercises the array scan path (< 8 elements)
  • DeepCycleDetection (11 depth): Exercises the hash set path (>= 8 elements)
  • DeepChainNoCycle: Validates deep import chains without cycles still work
  • DeepCrossFileCycle: Tests cycle detection across multiple files

This aligns well with the threshold of 8 in the implementation.


1-3: The describe function does not require an explicit import in Bun test files. Bun's test runner automatically injects Jest-like globals (describe, test, expect) into test files during transpilation, making explicit imports optional. The code is correct as-is.

bench/module-loader/run-benchmark.sh (1)

1-34: Ensure ./bench/module-loader/import.mjs exists in the repository.

The benchmark script references ./bench/module-loader/import.mjs for running benchmarks and needs this file to be present for the script to function correctly.

Comment on lines +13 to +16
START=$(date +%s%3N)
./build/debug/bun-debug ./bench/module-loader/import.mjs > /tmp/bench-output.txt 2>&1
EXIT_CODE=$?
END=$(date +%s%3N)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Consider portability of date +%s%3N for milliseconds.

The %3N format specifier for nanoseconds is a GNU extension and may not work on BSD/macOS date. For broader compatibility, consider using:

-    START=$(date +%s%3N)
+    START=$(python3 -c 'import time; print(int(time.time() * 1000))')

Alternatively, document that GNU coreutils is required.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
START=$(date +%s%3N)
./build/debug/bun-debug ./bench/module-loader/import.mjs > /tmp/bench-output.txt 2>&1
EXIT_CODE=$?
END=$(date +%s%3N)
START=$(python3 -c 'import time; print(int(time.time() * 1000))')
./build/debug/bun-debug ./bench/module-loader/import.mjs > /tmp/bench-output.txt 2>&1
EXIT_CODE=$?
END=$(date +%s%3N)
🤖 Prompt for AI Agents
In bench/module-loader/run-benchmark.sh around lines 13 to 16, the script uses
the GNU-only date format `date +%s%3N` to capture milliseconds which fails on
BSD/macOS; replace it with a portable approach such as calling Python/Perl to
compute epoch milliseconds (for example invoke a small one-liner that prints
int(time.time()*1000)) or detect and prefer GNU `gdate` if present, and add a
clear fallback/error that documents the dependency if neither option is
available; ensure both START and END use the same portable method and preserve
existing exit-code capture and timing calculation.

Comment on lines 2759 to 2773
/// Hash context for ImportTracker used in cycle detection
const ImportTrackerHashCtx = struct {
pub fn hash(_: @This(), tracker: ImportTracker) u64 {
// Combine source_index (u32) and import_ref hash (u64)
// name_loc is not included in the hash as it doesn't affect semantic equality
const source_hash = @as(u64, tracker.source_index.get());
const ref_hash = tracker.import_ref.hash64();
return source_hash ^ ref_hash;
}

pub fn eql(_: @This(), a: ImportTracker, b: ImportTracker) bool {
return a.source_index.get() == b.source_index.get() and
a.import_ref.eql(b.import_ref);
}
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Consider improving hash distribution.

The XOR of a small source_index (u32 cast to u64) with a full u64 ref_hash may not distribute well when source indices are small (common case). Consider mixing more thoroughly:

 pub fn hash(_: @This(), tracker: ImportTracker) u64 {
-    const source_hash = @as(u64, tracker.source_index.get());
-    const ref_hash = tracker.import_ref.hash64();
-    return source_hash ^ ref_hash;
+    var h: u64 = tracker.source_index.get();
+    h = h *% 0x9E3779B97F4A7C15; // golden ratio mixing
+    h ^= tracker.import_ref.hash64();
+    return h;
 }

That said, for cycle detection the collision rate is unlikely to cause correctness issues since eql is called on collisions, and performance impact should be minimal given the typical cycle sizes.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
/// Hash context for ImportTracker used in cycle detection
const ImportTrackerHashCtx = struct {
pub fn hash(_: @This(), tracker: ImportTracker) u64 {
// Combine source_index (u32) and import_ref hash (u64)
// name_loc is not included in the hash as it doesn't affect semantic equality
const source_hash = @as(u64, tracker.source_index.get());
const ref_hash = tracker.import_ref.hash64();
return source_hash ^ ref_hash;
}
pub fn eql(_: @This(), a: ImportTracker, b: ImportTracker) bool {
return a.source_index.get() == b.source_index.get() and
a.import_ref.eql(b.import_ref);
}
};
/// Hash context for ImportTracker used in cycle detection
const ImportTrackerHashCtx = struct {
pub fn hash(_: @This(), tracker: ImportTracker) u64 {
// Combine source_index (u32) and import_ref hash (u64)
// name_loc is not included in the hash as it doesn't affect semantic equality
var h: u64 = tracker.source_index.get();
h = h *% 0x9E3779B97F4A7C15; // golden ratio mixing
h ^= tracker.import_ref.hash64();
return h;
}
pub fn eql(_: @This(), a: ImportTracker, b: ImportTracker) bool {
return a.source_index.get() == b.source_index.get() and
a.import_ref.eql(b.import_ref);
}
};

@Jarred-Sumner
Copy link
Collaborator

Thanks for this

Was the benchmark in a release build?

@anonrig
Copy link
Author

anonrig commented Dec 8, 2025

Thanks for this

Was the benchmark in a release build?

Yes @Jarred-Sumner

Copy link
Collaborator

@Jarred-Sumner Jarred-Sumner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM if bundler tests pass

There will be a few unrelated test failures our CI needs some fixes

Copy link
Member

@cirospaciari cirospaciari left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM lets wait CI before merge

Copy link
Member

@cirospaciari cirospaciari left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like the test test/bundler/bundler_cycle_detection.test.ts is failing in all platforms, the other failures are not related

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 438cd79 and a1ef4de.

📒 Files selected for processing (1)
  • test/bundler/bundler_cycle_detection.test.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
test/**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/writing-tests.mdc)

test/**/*.{js,ts,jsx,tsx}: Write tests as JavaScript and TypeScript files using Jest-style APIs (test, describe, expect) and import from bun:test
Use test.each and data-driven tests to reduce boilerplate when testing multiple similar cases

Files:

  • test/bundler/bundler_cycle_detection.test.ts
test/**/*.test.{ts,js,jsx,tsx,mjs,cjs}

📄 CodeRabbit inference engine (test/CLAUDE.md)

test/**/*.test.{ts,js,jsx,tsx,mjs,cjs}: Use bun:test with files that end in *.test.{ts,js,jsx,tsx,mjs,cjs}
Do not write flaky tests. Never wait for time to pass in tests; always wait for the condition to be met instead of using an arbitrary amount of time
Never use hardcoded port numbers in tests. Always use port: 0 to get a random port
Prefer concurrent tests over sequential tests using test.concurrent or describe.concurrent when multiple tests spawn processes or write files, unless it's very difficult to make them concurrent
When spawning Bun processes in tests, use bunExe and bunEnv from harness to ensure the same build of Bun is used and debug logging is silenced
Use -e flag for single-file tests when spawning Bun processes
Use tempDir() from harness to create temporary directories with files for multi-file tests instead of creating files manually
Prefer async/await over callbacks in tests
When callbacks must be used and it's just a single callback, use Promise.withResolvers to create a promise that can be resolved or rejected from a callback
Do not set a timeout on tests. Bun already has timeouts
Use Buffer.alloc(count, fill).toString() instead of 'A'.repeat(count) to create repetitive strings in tests, as ''.repeat is very slow in debug JavaScriptCore builds
Use describe blocks for grouping related tests
Always use await using or using to ensure proper resource cleanup in tests for APIs like Bun.listen, Bun.connect, Bun.spawn, Bun.serve, etc
Always check exit codes and test error scenarios in error tests
Use describe.each() for parameterized tests
Use toMatchSnapshot() for snapshot testing
Use beforeAll(), afterEach(), beforeEach() for setup/teardown in tests
Track resources (servers, clients) in arrays for cleanup in afterEach()

Files:

  • test/bundler/bundler_cycle_detection.test.ts
test/**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

test/**/*.test.{ts,tsx}: For single-file tests in Bun test suite, prefer using -e flag over tempDir
For multi-file tests in Bun test suite, prefer using tempDir and Bun.spawn
Always use port: 0 when spawning servers in tests - do not hardcode ports or use custom random port functions
Use normalizeBunSnapshot to normalize snapshot output in tests instead of manual output comparison
Never write tests that check for no 'panic', 'uncaught exception', or similar strings in test output - that is not a valid test
Use tempDir from harness to create temporary directories in tests - do not use tmpdirSync or fs.mkdtempSync
In tests, call expect(stdout).toBe(...) before expect(exitCode).toBe(0) when spawning processes for more useful error messages on failure
Do not write flaky tests - do not use setTimeout in tests; instead await the condition to be met since you're testing the CONDITION, not TIME PASSING
Verify your test fails with USE_SYSTEM_BUN=1 bun test <file> and passes with bun bd test <file> - tests are not valid if they pass with USE_SYSTEM_BUN=1
Avoid shell commands in tests - do not use find or grep; use Bun's Glob and built-in tools instead
Test files must end in .test.ts or .test.tsx and be created in the appropriate test folder structure

Files:

  • test/bundler/bundler_cycle_detection.test.ts
🧠 Learnings (14)
📓 Common learnings
Learnt from: CR
Repo: oven-sh/bun PR: 0
File: .cursor/rules/dev-server-tests.mdc:0-0
Timestamp: 2025-11-24T18:35:08.612Z
Learning: Applies to test/bake/dev/bundle.test.ts : Organize bundle tests in bundle.test.ts for tests concerning bundling bugs that only occur in DevServer
Learnt from: CR
Repo: oven-sh/bun PR: 0
File: test/CLAUDE.md:0-0
Timestamp: 2025-11-24T18:37:30.259Z
Learning: Unit tests for specific features are organized by module (e.g., `/test/js/bun/`, `/test/js/node/`)
Learnt from: CR
Repo: oven-sh/bun PR: 0
File: src/bun.js/bindings/v8/CLAUDE.md:0-0
Timestamp: 2025-11-24T18:36:59.706Z
Learning: Applies to src/bun.js/bindings/v8/test/v8/v8.test.ts : Add corresponding test cases to test/v8/v8.test.ts using checkSameOutput() function to compare Node.js and Bun output
Learnt from: CR
Repo: oven-sh/bun PR: 0
File: .cursor/rules/registering-bun-modules.mdc:0-0
Timestamp: 2025-11-24T18:35:39.205Z
Learning: Add tests for new Bun runtime functionality
Learnt from: CR
Repo: oven-sh/bun PR: 0
File: .cursor/rules/dev-server-tests.mdc:0-0
Timestamp: 2025-11-24T18:35:08.612Z
Learning: Applies to test/bake/dev/esm.test.ts : Organize ESM tests in esm.test.ts for tests about various ESM features in development mode
Learnt from: CR
Repo: oven-sh/bun PR: 0
File: src/js/CLAUDE.md:0-0
Timestamp: 2025-11-24T18:37:11.466Z
Learning: Write JS builtins for Bun's Node.js compatibility and APIs, and run `bun bd` after changes
Learnt from: CR
Repo: oven-sh/bun PR: 0
File: src/bun.js/bindings/v8/CLAUDE.md:0-0
Timestamp: 2025-11-24T18:36:59.706Z
Learning: Ensure V8 API tests compare identical C++ code output between Node.js and Bun through the test suite validation process
Learnt from: CR
Repo: oven-sh/bun PR: 0
File: src/js/CLAUDE.md:0-0
Timestamp: 2025-11-24T18:37:11.466Z
Learning: Applies to src/js/{builtins,node,bun,thirdparty,internal}/**/*.{ts,js} : Use `process.platform` and `process.arch` for platform detection; these values are inlined and dead-code eliminated at build time
Learnt from: CR
Repo: oven-sh/bun PR: 0
File: test/CLAUDE.md:0-0
Timestamp: 2025-11-24T18:37:30.259Z
Learning: Applies to test/**/*.test.{ts,js,jsx,tsx,mjs,cjs} : When spawning Bun processes in tests, use `bunExe` and `bunEnv` from `harness` to ensure the same build of Bun is used and debug logging is silenced
Learnt from: RiskyMH
Repo: oven-sh/bun PR: 24719
File: docs/bundler/executables.mdx:527-560
Timestamp: 2025-11-14T16:07:01.064Z
Learning: In the Bun repository, certain bundler features like compile with code splitting (--compile --splitting) are CLI-only and not supported in the Bun.build() JavaScript API. Tests for CLI-only features use backend: "cli" flag (e.g., test/bundler/bundler_compile_splitting.test.ts). The CompileBuildConfig interface correctly restricts these with splitting?: never;. When documenting CLI-only bundler features, add a note clarifying they're not available via the programmatic API.
📚 Learning: 2025-11-24T18:35:08.612Z
Learnt from: CR
Repo: oven-sh/bun PR: 0
File: .cursor/rules/dev-server-tests.mdc:0-0
Timestamp: 2025-11-24T18:35:08.612Z
Learning: Applies to test/bake/dev/bundle.test.ts : Organize bundle tests in bundle.test.ts for tests concerning bundling bugs that only occur in DevServer

Applied to files:

  • test/bundler/bundler_cycle_detection.test.ts
📚 Learning: 2025-11-24T18:35:08.612Z
Learnt from: CR
Repo: oven-sh/bun PR: 0
File: .cursor/rules/dev-server-tests.mdc:0-0
Timestamp: 2025-11-24T18:35:08.612Z
Learning: Applies to test/bake/dev/css.test.ts : Organize CSS tests in css.test.ts for tests concerning bundling bugs with CSS files

Applied to files:

  • test/bundler/bundler_cycle_detection.test.ts
📚 Learning: 2025-11-24T18:35:08.612Z
Learnt from: CR
Repo: oven-sh/bun PR: 0
File: .cursor/rules/dev-server-tests.mdc:0-0
Timestamp: 2025-11-24T18:35:08.612Z
Learning: Applies to test/bake/dev/esm.test.ts : Organize ESM tests in esm.test.ts for tests about various ESM features in development mode

Applied to files:

  • test/bundler/bundler_cycle_detection.test.ts
📚 Learning: 2025-11-24T18:35:08.612Z
Learnt from: CR
Repo: oven-sh/bun PR: 0
File: .cursor/rules/dev-server-tests.mdc:0-0
Timestamp: 2025-11-24T18:35:08.612Z
Learning: Applies to test/bake/dev/ecosystem.test.ts : Organize ecosystem tests in ecosystem.test.ts for tests involving ensuring certain libraries are correct; prefer testing concrete bugs over testing entire packages

Applied to files:

  • test/bundler/bundler_cycle_detection.test.ts
📚 Learning: 2025-11-24T18:35:08.612Z
Learnt from: CR
Repo: oven-sh/bun PR: 0
File: .cursor/rules/dev-server-tests.mdc:0-0
Timestamp: 2025-11-24T18:35:08.612Z
Learning: Applies to test/bake/dev/sourcemap.test.ts : Organize source-map tests in sourcemap.test.ts for tests verifying source-maps are correct

Applied to files:

  • test/bundler/bundler_cycle_detection.test.ts
📚 Learning: 2025-11-24T18:36:59.706Z
Learnt from: CR
Repo: oven-sh/bun PR: 0
File: src/bun.js/bindings/v8/CLAUDE.md:0-0
Timestamp: 2025-11-24T18:36:59.706Z
Learning: Applies to src/bun.js/bindings/v8/test/v8/v8.test.ts : Add corresponding test cases to test/v8/v8.test.ts using checkSameOutput() function to compare Node.js and Bun output

Applied to files:

  • test/bundler/bundler_cycle_detection.test.ts
📚 Learning: 2025-11-24T18:35:50.422Z
Learnt from: CR
Repo: oven-sh/bun PR: 0
File: .cursor/rules/writing-tests.mdc:0-0
Timestamp: 2025-11-24T18:35:50.422Z
Learning: Applies to test/**/*.{js,ts,jsx,tsx} : Write tests as JavaScript and TypeScript files using Jest-style APIs (`test`, `describe`, `expect`) and import from `bun:test`

Applied to files:

  • test/bundler/bundler_cycle_detection.test.ts
📚 Learning: 2025-11-24T18:35:08.612Z
Learnt from: CR
Repo: oven-sh/bun PR: 0
File: .cursor/rules/dev-server-tests.mdc:0-0
Timestamp: 2025-11-24T18:35:08.612Z
Learning: Applies to test/bake/**/*.test.ts : Specify expected bundling errors via the `errors` option when a client is expected to encounter an error; by default, a client opening a page to an error fails the test

Applied to files:

  • test/bundler/bundler_cycle_detection.test.ts
📚 Learning: 2025-11-24T18:35:50.422Z
Learnt from: CR
Repo: oven-sh/bun PR: 0
File: .cursor/rules/writing-tests.mdc:0-0
Timestamp: 2025-11-24T18:35:50.422Z
Learning: See `test/harness.ts` for common test utilities and helpers

Applied to files:

  • test/bundler/bundler_cycle_detection.test.ts
📚 Learning: 2025-12-02T05:59:51.485Z
Learnt from: CR
Repo: oven-sh/bun PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-02T05:59:51.485Z
Learning: Applies to test/**/*.test.{ts,tsx} : For multi-file tests in Bun test suite, prefer using `tempDir` and `Bun.spawn`

Applied to files:

  • test/bundler/bundler_cycle_detection.test.ts
📚 Learning: 2025-11-24T18:37:30.259Z
Learnt from: CR
Repo: oven-sh/bun PR: 0
File: test/CLAUDE.md:0-0
Timestamp: 2025-11-24T18:37:30.259Z
Learning: Unit tests for specific features are organized by module (e.g., `/test/js/bun/`, `/test/js/node/`)

Applied to files:

  • test/bundler/bundler_cycle_detection.test.ts
📚 Learning: 2025-10-19T02:44:46.354Z
Learnt from: theshadow27
Repo: oven-sh/bun PR: 23798
File: packages/bun-otel/context-propagation.test.ts:1-1
Timestamp: 2025-10-19T02:44:46.354Z
Learning: In the Bun repository, standalone packages under packages/ (e.g., bun-vscode, bun-inspector-protocol, bun-plugin-yaml, bun-plugin-svelte, bun-debug-adapter-protocol, bun-otel) co-locate their tests with package source code using *.test.ts files. This follows standard npm/monorepo patterns. The test/ directory hierarchy (test/js/bun/, test/cli/, test/js/node/) is reserved for testing Bun's core runtime APIs and built-in functionality, not standalone packages.

Applied to files:

  • test/bundler/bundler_cycle_detection.test.ts
📚 Learning: 2025-11-24T18:37:30.259Z
Learnt from: CR
Repo: oven-sh/bun PR: 0
File: test/CLAUDE.md:0-0
Timestamp: 2025-11-24T18:37:30.259Z
Learning: Applies to test/**/*.test.{ts,js,jsx,tsx,mjs,cjs} : When spawning Bun processes in tests, use `bunExe` and `bunEnv` from `harness` to ensure the same build of Bun is used and debug logging is silenced

Applied to files:

  • test/bundler/bundler_cycle_detection.test.ts
🧬 Code graph analysis (1)
test/bundler/bundler_cycle_detection.test.ts (1)
test/bundler/expectBundled.ts (1)
  • itBundled (1758-1792)

Comment on lines +1 to +130
import { itBundled } from "./expectBundled";

describe("bundler", () => {
// Test basic cycle detection (uses array scan path, < 8 depth)
itBundled("bundler/ShallowCycleDetection", {
files: {
"/entry.js": /* js */ `
export {a as b} from './entry'
export {b as c} from './entry'
export {c as d} from './entry'
export {d as a} from './entry'
`,
},
bundleErrors: {
"/entry.js": [
`Detected cycle while resolving import "a"`,
`Detected cycle while resolving import "b"`,
`Detected cycle while resolving import "c"`,
`Detected cycle while resolving import "d"`,
],
},
});

// Test deep cycle detection (should use hash set path, >= 8 depth)
itBundled("bundler/DeepCycleDetection", {
files: {
"/entry.js": /* js */ `
export {a as b} from './entry'
export {b as c} from './entry'
export {c as d} from './entry'
export {d as e} from './entry'
export {e as f} from './entry'
export {f as g} from './entry'
export {g as h} from './entry'
export {h as i} from './entry'
export {i as j} from './entry'
export {j as k} from './entry'
export {k as a} from './entry'
`,
},
bundleErrors: {
"/entry.js": [
`Detected cycle while resolving import "a"`,
`Detected cycle while resolving import "b"`,
`Detected cycle while resolving import "c"`,
`Detected cycle while resolving import "d"`,
`Detected cycle while resolving import "e"`,
`Detected cycle while resolving import "f"`,
`Detected cycle while resolving import "g"`,
`Detected cycle while resolving import "h"`,
`Detected cycle while resolving import "i"`,
`Detected cycle while resolving import "j"`,
`Detected cycle while resolving import "k"`,
],
},
});

// Test deep chain without cycle (should work correctly)
itBundled("bundler/DeepChainNoCycle", {
files: {
"/entry.js": /* js */ `
import { x } from './a.js';
console.log(x);
`,
"/a.js": /* js */ `
import { x } from './b.js';
export { x };
`,
"/b.js": /* js */ `
import { x } from './c.js';
export { x };
`,
"/c.js": /* js */ `
import { x } from './d.js';
export { x };
`,
"/d.js": /* js */ `
import { x } from './e.js';
export { x };
`,
"/e.js": /* js */ `
import { x } from './f.js';
export { x };
`,
"/f.js": /* js */ `
import { x } from './g.js';
export { x };
`,
"/g.js": /* js */ `
import { x } from './h.js';
export { x };
`,
"/h.js": /* js */ `
export const x = 42;
`,
},
run: {
stdout: "42",
},
});

// Test cross-file cycle detection with deep chain
itBundled("bundler/DeepCrossFileCycle", {
files: {
"/entry.js": /* js */ `
export {a as b} from './foo1'
export {b as c} from './foo1'
`,
"/foo1.js": /* js */ `
export {c as d} from './foo2'
export {d as e} from './foo2'
`,
"/foo2.js": /* js */ `
export {e as f} from './foo3'
export {f as g} from './foo3'
`,
"/foo3.js": /* js */ `
export {g as h} from './foo4'
export {h as i} from './foo4'
`,
"/foo4.js": /* js */ `
export {i as j} from './entry'
export {j as a} from './entry'
`,
},
bundleErrors: {
"/entry.js": [`Detected cycle while resolving import "a"`, `Detected cycle while resolving import "b"`],
},
});
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Excellent test coverage for cycle detection optimization!

The test suite comprehensively validates the hybrid cycle-detection optimization:

  • ShallowCycleDetection: Validates the array scan path (< 8 depth)
  • DeepCycleDetection: Validates the hash-set path (>= 8 depth)
  • DeepChainNoCycle: Confirms no false positives on deep non-cyclic chains
  • DeepCrossFileCycle: Tests real-world cross-file cycle scenarios

The tests follow all coding guidelines: proper use of itBundled, clear naming, no timing dependencies, and well-organized under describe("bundler").

Optional enhancement: Consider adding an edge-case test with exactly 8 items in the cycle to validate the threshold boundary behavior:

// Test threshold boundary (exactly 8 depth)
itBundled("bundler/ThresholdCycleDetection", {
  files: {
    "/entry.js": /* js */ `
      export {a as b} from './entry'
      export {b as c} from './entry'
      export {c as d} from './entry'
      export {d as e} from './entry'
      export {e as f} from './entry'
      export {f as g} from './entry'
      export {g as h} from './entry'
      export {h as a} from './entry'
    `,
  },
  bundleErrors: {
    "/entry.js": [
      `Detected cycle while resolving import "a"`,
      `Detected cycle while resolving import "b"`,
      `Detected cycle while resolving import "c"`,
      `Detected cycle while resolving import "d"`,
      `Detected cycle while resolving import "e"`,
      `Detected cycle while resolving import "f"`,
      `Detected cycle while resolving import "g"`,
      `Detected cycle while resolving import "h"`,
    ],
  },
});
🤖 Prompt for AI Agents
test/bundler/bundler_cycle_detection.test.ts lines 1-130: add a new test case
"bundler/ThresholdCycleDetection" that creates a cycle of exactly 8 exports
(a→b→c→d→e→f→g→h→a) and asserts bundleErrors list contains "Detected cycle while
resolving import" for each of a..h; insert it alongside the other itBundled
cases so the suite validates the threshold boundary between the array-scan and
hash-set cycle-detection paths.

@anonrig
Copy link
Author

anonrig commented Dec 9, 2025

looks like the test test/bundler/bundler_cycle_detection.test.ts is failing in all platforms, the other failures are not related

It seems I've written the include path wrong in the first place. Can you rerun CI @cirospaciari?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants