aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/bun.js/module_loader.zig38
-rw-r--r--src/cli/test_command.zig13
-rw-r--r--src/install/install.zig22
-rw-r--r--src/resolver/resolver.zig10
4 files changed, 56 insertions, 27 deletions
diff --git a/src/bun.js/module_loader.zig b/src/bun.js/module_loader.zig
index bee5fa1a1..ae415b65b 100644
--- a/src/bun.js/module_loader.zig
+++ b/src/bun.js/module_loader.zig
@@ -188,6 +188,7 @@ pub const ModuleLoader = struct {
// This is the specific state for making it async
poll_ref: JSC.PollRef = .{},
+ any_task: JSC.AnyTask = undefined,
pub const Id = u32;
const debug = Output.scoped(.ModuleLoader, false);
@@ -208,6 +209,7 @@ pub const ModuleLoader = struct {
pub const Queue = struct {
map: Map = .{},
+ scheduled: u32 = 0,
concurrent_task_count: std.atomic.Atomic(u32) = std.atomic.Atomic(u32).init(0),
const DeferredDependencyError = struct {
@@ -273,9 +275,11 @@ pub const ModuleLoader = struct {
var pm = this.vm().packageManager();
this.runTasks();
+ _ = pm.scheduleNetworkTasks();
+ this.runTasks();
+
this.pollModules();
_ = pm.flushDependencyQueue();
- _ = pm.scheduleNetworkTasks();
}
pub fn runTasks(this: *Queue) void {
@@ -414,8 +418,11 @@ pub const ModuleLoader = struct {
pub fn pollModules(this: *Queue) void {
var pm = this.vm().packageManager();
- var modules = this.map.items;
+ if (pm.pending_tasks > 0) return;
+
+ var modules: []AsyncModule = this.map.items;
var i: usize = 0;
+
for (modules) |mod| {
var module = mod;
var tags = module.parse_result.pending_imports.items(.tag);
@@ -459,8 +466,14 @@ pub const ModuleLoader = struct {
switch (pm.determinePreinstallState(package, pm.lockfile)) {
.done => {
- done_count += 1;
- tags[tag_i] = .done;
+ // we are only truly done if all the dependencies are done.
+ const current_tasks = pm.total_tasks;
+ // so if enqueuing all the dependencies produces no new tasks, we are done.
+ pm.enqueueDependencyList(package.dependencies, false);
+ if (current_tasks == pm.total_tasks) {
+ tags[tag_i] = .done;
+ done_count += 1;
+ }
},
.extracting => {
// we are extracting the package
@@ -473,9 +486,6 @@ pub const ModuleLoader = struct {
}
if (done_count == tags.len) {
- if (i + 1 >= modules.len) {
- this.vm().packageManager().endProgressBar();
- }
module.done(this.vm());
} else {
modules[i] = module;
@@ -529,6 +539,19 @@ pub const ModuleLoader = struct {
}
pub fn done(this: *AsyncModule, jsc_vm: *JSC.VirtualMachine) void {
+ var clone = jsc_vm.allocator.create(AsyncModule) catch unreachable;
+ clone.* = this.*;
+ jsc_vm.modules.scheduled += 1;
+ clone.any_task = JSC.AnyTask.New(AsyncModule, onDone).init(clone);
+ jsc_vm.enqueueTask(JSC.Task.init(&clone.any_task));
+ }
+
+ pub fn onDone(this: *AsyncModule) void {
+ var jsc_vm = this.globalThis.bunVM();
+ jsc_vm.modules.scheduled -= 1;
+ if (jsc_vm.modules.scheduled == 0) {
+ jsc_vm.packageManager().endProgressBar();
+ }
var log = logger.Log.init(jsc_vm.allocator);
defer log.deinit();
var errorable: ErrorableResolvedSource = undefined;
@@ -556,6 +579,7 @@ pub const ModuleLoader = struct {
&ref,
);
this.deinit();
+ jsc_vm.allocator.destroy(this);
}
pub fn resolveError(this: *AsyncModule, vm: *JSC.VirtualMachine, import_record_id: u32, result: PackageResolveError) !void {
diff --git a/src/cli/test_command.zig b/src/cli/test_command.zig
index 7b5c88947..ac210dfe2 100644
--- a/src/cli/test_command.zig
+++ b/src/cli/test_command.zig
@@ -480,6 +480,18 @@ pub const TestCommand = struct {
else => {},
}
+ {
+ vm.global.vm().drainMicrotasks();
+ var count = vm.unhandled_error_counter;
+ vm.global.handleRejectedPromises();
+ while (vm.unhandled_error_counter > count) {
+ count = vm.unhandled_error_counter;
+ vm.global.vm().drainMicrotasks();
+ vm.global.handleRejectedPromises();
+ }
+ vm.global.vm().doWork();
+ }
+
var modules: []*Jest.DescribeScope = reporter.jest.files.items(.module_scope)[file_start..];
for (modules) |module| {
vm.onUnhandledRejectionCtx = null;
@@ -501,5 +513,6 @@ pub const TestCommand = struct {
_ = vm.global.vm().runGC(false);
}
vm.global.vm().clearMicrotaskCallback();
+ vm.global.handleRejectedPromises();
}
};
diff --git a/src/install/install.zig b/src/install/install.zig
index a30fdb139..81db2128d 100644
--- a/src/install/install.zig
+++ b/src/install/install.zig
@@ -2791,8 +2791,6 @@ pub const PackageManager = struct {
var lockfile = this.lockfile;
var dependency_queue = &lockfile.scratch.dependency_list_queue;
- this.flushNetworkQueue();
-
while (dependency_queue.readItem()) |dependencies_list| {
var i: u32 = dependencies_list.off;
const end = dependencies_list.off + dependencies_list.len;
@@ -2804,16 +2802,19 @@ pub const PackageManager = struct {
false,
) catch {};
}
-
- this.flushNetworkQueue();
}
+
+ this.flushNetworkQueue();
}
pub fn flushDependencyQueue(this: *PackageManager) void {
- this.flushNetworkQueue();
- this.doFlushDependencyQueue();
- this.doFlushDependencyQueue();
- this.doFlushDependencyQueue();
- this.flushNetworkQueue();
+ var last_count = this.total_tasks;
+ while (true) : (last_count = this.total_tasks) {
+ this.flushNetworkQueue();
+ this.doFlushDependencyQueue();
+ this.flushNetworkQueue();
+
+ if (this.total_tasks == last_count) break;
+ }
}
pub fn scheduleNetworkTasks(manager: *PackageManager) usize {
@@ -2987,7 +2988,7 @@ pub const PackageManager = struct {
if (manager.dynamic_root_dependencies) |*root_deps| {
var deps: []Dependency.Pair = root_deps.items;
for (deps) |*dep| {
- if (strings.eql(manager.lockfile.str(dep.dependency.name), name.slice())) {
+ if (strings.eqlLong(manager.lockfile.str(dep.dependency.name), name.slice(), true)) {
dep.failed = dep.failed orelse err;
}
}
@@ -3153,7 +3154,6 @@ pub const PackageManager = struct {
try manager.processDependencyList(dependency_list, ExtractCompletionContext, extract_ctx, callbacks);
- manager.flushDependencyQueue();
continue;
}
}
diff --git a/src/resolver/resolver.zig b/src/resolver/resolver.zig
index b959445dc..309707dde 100644
--- a/src/resolver/resolver.zig
+++ b/src/resolver/resolver.zig
@@ -1543,22 +1543,14 @@ pub const Resolver = struct {
string_buf = package_json.dependencies.source_buf;
}
- var hash: u64 = std.math.maxInt(u64);
-
for (dependencies_list) |dependency, dependency_id| {
const dep_name_ = &dependency.name;
const dep_name = dep_name_.slice(string_buf);
if (dep_name.len == esm.name.len) {
- if (hash == std.math.maxInt(u64)) {
- hash = bun.hash(dep_name);
- }
-
- if (hash != dependency.name_hash) {
+ if (!strings.eqlLong(dep_name, esm.name, false)) {
continue;
}
- std.debug.assert(strings.eql(dep_name, esm.name));
-
dependency_version = dependency.version;
dependency_behavior = dependency.behavior;