mirror of
https://github.com/oven-sh/bun
synced 2026-02-17 22:32:06 +00:00
Fixes ENG-21287
Build times, from `bun run build && echo '//' >> src/main.zig && time
bun run build`
|Platform|0.14.1|0.15.2|Speedup|
|-|-|-|-|
|macos debug asan|126.90s|106.27s|1.19x|
|macos debug noasan|60.62s|50.85s|1.19x|
|linux debug asan|292.77s|241.45s|1.21x|
|linux debug noasan|146.58s|130.94s|1.12x|
|linux debug use_llvm=false|n/a|78.27s|1.87x|
|windows debug asan|177.13s|142.55s|1.24x|
Runtime performance:
- next build memory usage may have gone up by 5%. Otherwise seems the
same. Some code with writers may have gotten slower, especially one
instance of a counting writer and a few instances of unbuffered writers
that now have vtable overhead.
- File size reduced by 800kb (from 100.2mb to 99.4mb)
Improvements:
- `@export` hack is no longer needed for watch
- native x86_64 backend for linux builds faster. to use it, set use_llvm
false and no_link_obj false. also set `ASAN_OPTIONS=detect_leaks=0`
otherwise it will spam the output with tens of thousands of lines of
debug info errors. may need to use the zig lldb fork for debugging.
- zig test-obj, which we will be able to use for zig unit tests
Still an issue:
- false 'dependency loop' errors remain in watch mode
- watch mode crashes observed
Follow-up:
- [ ] search `comptime Writer: type` and `comptime W: type` and remove
- [ ] remove format_mode in our zig fork
- [ ] remove deprecated.zig autoFormatLabelFallback
- [ ] remove deprecated.zig autoFormatLabel
- [ ] remove deprecated.BufferedWriter and BufferedReader
- [ ] remove override_no_export_cpp_apis as it is no longer needed
- [ ] css Parser(W) -> Parser, and remove all the comptime writer: type
params
- [ ] remove deprecated writer fully
Files that add lines:
```
649 src/deprecated.zig
167 scripts/pack-codegen-for-zig-team.ts
54 scripts/cleartrace-impl.js
46 scripts/cleartrace.ts
43 src/windows.zig
18 src/fs.zig
17 src/bun.js/ConsoleObject.zig
16 src/output.zig
12 src/bun.js/test/debug.zig
12 src/bun.js/node/node_fs.zig
8 src/env_loader.zig
7 src/css/printer.zig
7 src/cli/init_command.zig
7 src/bun.js/node.zig
6 src/string/escapeRegExp.zig
6 src/install/PnpmMatcher.zig
5 src/bun.js/webcore/Blob.zig
4 src/crash_handler.zig
4 src/bun.zig
3 src/install/lockfile/bun.lock.zig
3 src/cli/update_interactive_command.zig
3 src/cli/pack_command.zig
3 build.zig
2 src/Progress.zig
2 src/install/lockfile/lockfile_json_stringify_for_debugging.zig
2 src/css/small_list.zig
2 src/bun.js/webcore/prompt.zig
1 test/internal/ban-words.test.ts
1 test/internal/ban-limits.json
1 src/watcher/WatcherTrace.zig
1 src/transpiler.zig
1 src/shell/builtin/cp.zig
1 src/js_printer.zig
1 src/io/PipeReader.zig
1 src/install/bin.zig
1 src/css/selectors/selector.zig
1 src/cli/run_command.zig
1 src/bun.js/RuntimeTranspilerStore.zig
1 src/bun.js/bindings/JSRef.zig
1 src/bake/DevServer.zig
```
Files that remove lines:
```
-1 src/test/recover.zig
-1 src/sql/postgres/SocketMonitor.zig
-1 src/sql/mysql/MySQLRequestQueue.zig
-1 src/sourcemap/CodeCoverage.zig
-1 src/css/values/color_js.zig
-1 src/compile_target.zig
-1 src/bundler/linker_context/convertStmtsForChunk.zig
-1 src/bundler/bundle_v2.zig
-1 src/bun.js/webcore/blob/read_file.zig
-1 src/ast/base.zig
-2 src/sql/postgres/protocol/ArrayList.zig
-2 src/shell/builtin/mkdir.zig
-2 src/install/PackageManager/patchPackage.zig
-2 src/install/PackageManager/PackageManagerDirectories.zig
-2 src/fmt.zig
-2 src/css/declaration.zig
-2 src/css/css_parser.zig
-2 src/collections/baby_list.zig
-2 src/bun.js/bindings/ZigStackFrame.zig
-2 src/ast/E.zig
-3 src/StandaloneModuleGraph.zig
-3 src/deps/picohttp.zig
-3 src/deps/libuv.zig
-3 src/btjs.zig
-4 src/threading/Futex.zig
-4 src/shell/builtin/touch.zig
-4 src/meta.zig
-4 src/install/lockfile.zig
-4 src/css/selectors/parser.zig
-5 src/shell/interpreter.zig
-5 src/css/error.zig
-5 src/bun.js/web_worker.zig
-5 src/bun.js.zig
-6 src/cli/test_command.zig
-6 src/bun.js/VirtualMachine.zig
-6 src/bun.js/uuid.zig
-6 src/bun.js/bindings/JSValue.zig
-9 src/bun.js/test/pretty_format.zig
-9 src/bun.js/api/BunObject.zig
-14 src/install/install_binding.zig
-14 src/fd.zig
-14 src/bun.js/node/path.zig
-14 scripts/pack-codegen-for-zig-team.sh
-17 src/bun.js/test/diff_format.zig
```
`git diff --numstat origin/main...HEAD | awk '{ print ($1-$2)"\t"$3 }' |
sort -rn`
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Dylan Conway <dylan.conway567@gmail.com>
Co-authored-by: Meghan Denny <meghan@bun.com>
Co-authored-by: tayor.fish <contact@taylor.fish>
450 lines
16 KiB
Zig
450 lines
16 KiB
Zig
path_or_port: ?[]const u8 = null,
|
|
from_environment_variable: []const u8 = "",
|
|
script_execution_context_id: u32 = 0,
|
|
next_debugger_id: u64 = 1,
|
|
poll_ref: bun.Async.KeepAlive = .{},
|
|
wait_for_connection: Wait = .off,
|
|
// wait_for_connection: bool = false,
|
|
set_breakpoint_on_first_line: bool = false,
|
|
mode: enum {
|
|
/// Bun acts as the server. https://debug.bun.sh/ uses this
|
|
listen,
|
|
/// Bun connects to this path. The VSCode extension uses this.
|
|
connect,
|
|
} = .listen,
|
|
|
|
test_reporter_agent: TestReporterAgent = .{},
|
|
lifecycle_reporter_agent: LifecycleAgent = .{},
|
|
frontend_dev_server_agent: BunFrontendDevServerAgent = .{},
|
|
http_server_agent: HTTPServerAgent = .{},
|
|
must_block_until_connected: bool = false,
|
|
|
|
pub const Wait = enum { off, shortly, forever };
|
|
|
|
pub const log = Output.scoped(.debugger, .visible);
|
|
|
|
extern "c" fn Bun__createJSDebugger(*JSGlobalObject) u32;
|
|
extern "c" fn Bun__ensureDebugger(u32, bool) void;
|
|
extern "c" fn Bun__startJSDebuggerThread(*JSGlobalObject, u32, *bun.String, c_int, bool) void;
|
|
var futex_atomic: std.atomic.Value(u32) = .init(0);
|
|
|
|
pub fn waitForDebuggerIfNecessary(this: *VirtualMachine) void {
|
|
const debugger = &(this.debugger orelse return);
|
|
if (!debugger.must_block_until_connected) {
|
|
return;
|
|
}
|
|
defer debugger.must_block_until_connected = false;
|
|
|
|
Debugger.log("spin", .{});
|
|
while (futex_atomic.load(.monotonic) > 0) {
|
|
bun.Futex.waitForever(&futex_atomic, 1);
|
|
}
|
|
if (comptime Environment.enable_logs)
|
|
Debugger.log("waitForDebugger: {f}", .{Output.ElapsedFormatter{
|
|
.colors = Output.enable_ansi_colors_stderr,
|
|
.duration_ns = @truncate(@as(u128, @intCast(std.time.nanoTimestamp() - bun.cli.start_time))),
|
|
}});
|
|
|
|
Bun__ensureDebugger(debugger.script_execution_context_id, debugger.wait_for_connection != .off);
|
|
|
|
// Sleep up to 30ms for automatic inspection.
|
|
const wait_for_connection_delay_ms = 30;
|
|
|
|
var deadline: bun.timespec = if (debugger.wait_for_connection == .shortly) bun.timespec.now().addMs(wait_for_connection_delay_ms) else undefined;
|
|
|
|
if (comptime Environment.isWindows) {
|
|
// TODO: remove this when tickWithTimeout actually works properly on Windows.
|
|
if (debugger.wait_for_connection == .shortly) {
|
|
uv.uv_update_time(this.uvLoop());
|
|
var timer = bun.handleOom(bun.default_allocator.create(uv.Timer));
|
|
timer.* = std.mem.zeroes(uv.Timer);
|
|
timer.init(this.uvLoop());
|
|
const onDebuggerTimer = struct {
|
|
fn call(handle: *uv.Timer) callconv(.c) void {
|
|
const vm = VirtualMachine.get();
|
|
vm.debugger.?.poll_ref.unref(vm);
|
|
uv.uv_close(@ptrCast(handle), deinitTimer);
|
|
}
|
|
|
|
fn deinitTimer(handle: *anyopaque) callconv(.c) void {
|
|
bun.default_allocator.destroy(@as(*uv.Timer, @ptrCast(@alignCast(handle))));
|
|
}
|
|
}.call;
|
|
timer.start(wait_for_connection_delay_ms, 0, &onDebuggerTimer);
|
|
timer.ref();
|
|
}
|
|
}
|
|
|
|
while (debugger.wait_for_connection != .off) {
|
|
this.eventLoop().tick();
|
|
switch (debugger.wait_for_connection) {
|
|
.forever => {
|
|
this.eventLoop().autoTickActive();
|
|
|
|
if (comptime Environment.enable_logs)
|
|
log("waited: {D}", .{@as(i64, @truncate(std.time.nanoTimestamp() - bun.cli.start_time))});
|
|
},
|
|
.shortly => {
|
|
// Handle .incrementRefConcurrently
|
|
if (comptime Environment.isPosix) {
|
|
const pending_unref = this.pending_unref_counter;
|
|
if (pending_unref > 0) {
|
|
this.pending_unref_counter = 0;
|
|
this.uwsLoop().unrefCount(pending_unref);
|
|
}
|
|
}
|
|
|
|
this.uwsLoop().tickWithTimeout(&deadline);
|
|
|
|
if (comptime Environment.enable_logs)
|
|
log("waited: {D}", .{@as(i64, @truncate(std.time.nanoTimestamp() - bun.cli.start_time))});
|
|
|
|
const elapsed = bun.timespec.now();
|
|
if (elapsed.order(&deadline) != .lt) {
|
|
debugger.poll_ref.unref(this);
|
|
log("Timed out waiting for the debugger", .{});
|
|
break;
|
|
}
|
|
},
|
|
.off => {
|
|
break;
|
|
},
|
|
}
|
|
}
|
|
}
|
|
|
|
pub var has_created_debugger: bool = false;
|
|
pub fn create(this: *VirtualMachine, globalObject: *JSGlobalObject) !void {
|
|
log("create", .{});
|
|
jsc.markBinding(@src());
|
|
if (!has_created_debugger) {
|
|
has_created_debugger = true;
|
|
std.mem.doNotOptimizeAway(&TestReporterAgent.Bun__TestReporterAgentDisable);
|
|
std.mem.doNotOptimizeAway(&LifecycleAgent.Bun__LifecycleAgentDisable);
|
|
std.mem.doNotOptimizeAway(&TestReporterAgent.Bun__TestReporterAgentEnable);
|
|
std.mem.doNotOptimizeAway(&LifecycleAgent.Bun__LifecycleAgentEnable);
|
|
var debugger = &this.debugger.?;
|
|
debugger.script_execution_context_id = Bun__createJSDebugger(globalObject);
|
|
if (!this.has_started_debugger) {
|
|
this.has_started_debugger = true;
|
|
var thread = try std.Thread.spawn(.{}, startJSDebuggerThread, .{this});
|
|
thread.detach();
|
|
}
|
|
this.eventLoop().ensureWaker();
|
|
|
|
if (debugger.wait_for_connection != .off) {
|
|
debugger.poll_ref.ref(this);
|
|
debugger.must_block_until_connected = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn startJSDebuggerThread(other_vm: *VirtualMachine) void {
|
|
var arena = bun.MimallocArena.init();
|
|
Output.Source.configureNamedThread("Debugger");
|
|
log("startJSDebuggerThread", .{});
|
|
jsc.markBinding(@src());
|
|
|
|
// Create a thread-local env_loader to avoid allocator threading violations
|
|
const thread_allocator = arena.allocator();
|
|
const env_map = thread_allocator.create(DotEnv.Map) catch @panic("Failed to create debugger env map");
|
|
env_map.* = DotEnv.Map.init(thread_allocator);
|
|
const env_loader = thread_allocator.create(DotEnv.Loader) catch @panic("Failed to create debugger env loader");
|
|
env_loader.* = DotEnv.Loader.init(env_map, thread_allocator);
|
|
|
|
var vm = VirtualMachine.init(.{
|
|
.allocator = thread_allocator,
|
|
.args = std.mem.zeroes(bun.schema.api.TransformOptions),
|
|
.store_fd = false,
|
|
.env_loader = env_loader,
|
|
}) catch @panic("Failed to create Debugger VM");
|
|
vm.allocator = arena.allocator();
|
|
vm.arena = &arena;
|
|
|
|
vm.transpiler.configureDefines() catch @panic("Failed to configure defines");
|
|
vm.is_main_thread = false;
|
|
vm.eventLoop().ensureWaker();
|
|
|
|
const callback = jsc.OpaqueWrap(VirtualMachine, start);
|
|
vm.global.vm().holdAPILock(other_vm, callback);
|
|
}
|
|
|
|
pub export fn Debugger__didConnect() void {
|
|
var this = VirtualMachine.get();
|
|
if (this.debugger.?.wait_for_connection != .off) {
|
|
this.debugger.?.wait_for_connection = .off;
|
|
this.debugger.?.poll_ref.unref(this);
|
|
this.eventLoop().wakeup();
|
|
}
|
|
}
|
|
|
|
fn start(other_vm: *VirtualMachine) void {
|
|
jsc.markBinding(@src());
|
|
|
|
var this = VirtualMachine.get();
|
|
const debugger = other_vm.debugger.?;
|
|
const loop = this.eventLoop();
|
|
|
|
if (debugger.from_environment_variable.len > 0) {
|
|
var url = bun.String.cloneUTF8(debugger.from_environment_variable);
|
|
|
|
loop.enter();
|
|
defer loop.exit();
|
|
Bun__startJSDebuggerThread(this.global, debugger.script_execution_context_id, &url, 1, debugger.mode == .connect);
|
|
}
|
|
|
|
if (debugger.path_or_port) |path_or_port| {
|
|
var url = bun.String.cloneUTF8(path_or_port);
|
|
|
|
loop.enter();
|
|
defer loop.exit();
|
|
Bun__startJSDebuggerThread(this.global, debugger.script_execution_context_id, &url, 0, debugger.mode == .connect);
|
|
}
|
|
|
|
this.global.handleRejectedPromises();
|
|
|
|
if (this.log.msgs.items.len > 0) {
|
|
this.log.print(Output.errorWriter()) catch {};
|
|
Output.prettyErrorln("\n", .{});
|
|
Output.flush();
|
|
}
|
|
|
|
log("wake", .{});
|
|
futex_atomic.store(0, .monotonic);
|
|
bun.Futex.wake(&futex_atomic, 1);
|
|
|
|
other_vm.eventLoop().wakeup();
|
|
|
|
this.eventLoop().tick();
|
|
|
|
other_vm.eventLoop().wakeup();
|
|
|
|
while (true) {
|
|
while (this.isEventLoopAlive()) {
|
|
this.tick();
|
|
this.eventLoop().autoTickActive();
|
|
}
|
|
|
|
this.eventLoop().tickPossiblyForever();
|
|
}
|
|
}
|
|
|
|
pub const AsyncTaskTracker = struct {
|
|
id: u64,
|
|
|
|
pub fn init(vm: *VirtualMachine) AsyncTaskTracker {
|
|
return .{ .id = vm.nextAsyncTaskID() };
|
|
}
|
|
|
|
pub fn didSchedule(this: AsyncTaskTracker, globalObject: *JSGlobalObject) void {
|
|
if (this.id == 0) return;
|
|
|
|
didScheduleAsyncCall(globalObject, AsyncCallType.EventListener, this.id, true);
|
|
}
|
|
|
|
pub fn didCancel(this: AsyncTaskTracker, globalObject: *JSGlobalObject) void {
|
|
if (this.id == 0) return;
|
|
|
|
didCancelAsyncCall(globalObject, AsyncCallType.EventListener, this.id);
|
|
}
|
|
|
|
pub fn willDispatch(this: AsyncTaskTracker, globalObject: *JSGlobalObject) void {
|
|
if (this.id == 0) {
|
|
return;
|
|
}
|
|
|
|
willDispatchAsyncCall(globalObject, AsyncCallType.EventListener, this.id);
|
|
}
|
|
|
|
pub fn didDispatch(this: AsyncTaskTracker, globalObject: *JSGlobalObject) void {
|
|
if (this.id == 0) {
|
|
return;
|
|
}
|
|
|
|
didDispatchAsyncCall(globalObject, AsyncCallType.EventListener, this.id);
|
|
}
|
|
};
|
|
|
|
pub const AsyncCallType = enum(u8) {
|
|
DOMTimer = 1,
|
|
EventListener = 2,
|
|
PostMessage = 3,
|
|
RequestAnimationFrame = 4,
|
|
Microtask = 5,
|
|
};
|
|
extern fn Debugger__didScheduleAsyncCall(*JSGlobalObject, AsyncCallType, u64, bool) void;
|
|
extern fn Debugger__didCancelAsyncCall(*JSGlobalObject, AsyncCallType, u64) void;
|
|
extern fn Debugger__didDispatchAsyncCall(*JSGlobalObject, AsyncCallType, u64) void;
|
|
extern fn Debugger__willDispatchAsyncCall(*JSGlobalObject, AsyncCallType, u64) void;
|
|
|
|
pub fn didScheduleAsyncCall(globalObject: *JSGlobalObject, call: AsyncCallType, id: u64, single_shot: bool) void {
|
|
jsc.markBinding(@src());
|
|
Debugger__didScheduleAsyncCall(globalObject, call, id, single_shot);
|
|
}
|
|
pub fn didCancelAsyncCall(globalObject: *JSGlobalObject, call: AsyncCallType, id: u64) void {
|
|
jsc.markBinding(@src());
|
|
Debugger__didCancelAsyncCall(globalObject, call, id);
|
|
}
|
|
pub fn didDispatchAsyncCall(globalObject: *JSGlobalObject, call: AsyncCallType, id: u64) void {
|
|
jsc.markBinding(@src());
|
|
Debugger__didDispatchAsyncCall(globalObject, call, id);
|
|
}
|
|
pub fn willDispatchAsyncCall(globalObject: *JSGlobalObject, call: AsyncCallType, id: u64) void {
|
|
jsc.markBinding(@src());
|
|
Debugger__willDispatchAsyncCall(globalObject, call, id);
|
|
}
|
|
|
|
pub const TestReporterAgent = struct {
|
|
handle: ?*Handle = null,
|
|
const debug = Output.scoped(.TestReporterAgent, .visible);
|
|
|
|
/// this enum is kept in sync with c++ InspectorTestReporterAgent.cpp `enum class BunTestStatus`
|
|
pub const TestStatus = enum(u8) {
|
|
pass,
|
|
fail,
|
|
timeout,
|
|
skip,
|
|
todo,
|
|
skipped_because_label,
|
|
};
|
|
|
|
pub const TestType = enum(u8) {
|
|
@"test" = 0,
|
|
describe = 1,
|
|
};
|
|
|
|
pub const Handle = opaque {
|
|
extern "c" fn Bun__TestReporterAgentReportTestFound(agent: *Handle, callFrame: *jsc.CallFrame, testId: c_int, name: *bun.String, item_type: TestType, parentId: c_int) void;
|
|
extern "c" fn Bun__TestReporterAgentReportTestStart(agent: *Handle, testId: c_int) void;
|
|
extern "c" fn Bun__TestReporterAgentReportTestEnd(agent: *Handle, testId: c_int, bunTestStatus: TestStatus, elapsed: f64) void;
|
|
|
|
pub fn reportTestFound(this: *Handle, callFrame: *jsc.CallFrame, testId: i32, name: *bun.String, item_type: TestType, parentId: i32) void {
|
|
Bun__TestReporterAgentReportTestFound(this, callFrame, testId, name, item_type, parentId);
|
|
}
|
|
|
|
pub fn reportTestStart(this: *Handle, testId: c_int) void {
|
|
Bun__TestReporterAgentReportTestStart(this, testId);
|
|
}
|
|
|
|
pub fn reportTestEnd(this: *Handle, testId: c_int, bunTestStatus: TestStatus, elapsed: f64) void {
|
|
Bun__TestReporterAgentReportTestEnd(this, testId, bunTestStatus, elapsed);
|
|
}
|
|
};
|
|
pub export fn Bun__TestReporterAgentEnable(agent: *Handle) void {
|
|
if (VirtualMachine.get().debugger) |*debugger| {
|
|
debug("enable", .{});
|
|
debugger.test_reporter_agent.handle = agent;
|
|
}
|
|
}
|
|
pub export fn Bun__TestReporterAgentDisable(_: *Handle) void {
|
|
if (VirtualMachine.get().debugger) |*debugger| {
|
|
debug("disable", .{});
|
|
debugger.test_reporter_agent.handle = null;
|
|
}
|
|
}
|
|
|
|
/// Caller must ensure that it is enabled first.
|
|
///
|
|
/// Since we may have to call .deinit on the name string.
|
|
pub fn reportTestFound(this: TestReporterAgent, callFrame: *jsc.CallFrame, test_id: i32, name: *bun.String, item_type: TestType, parentId: i32) void {
|
|
debug("reportTestFound", .{});
|
|
|
|
this.handle.?.reportTestFound(callFrame, test_id, name, item_type, parentId);
|
|
}
|
|
|
|
/// Caller must ensure that it is enabled first.
|
|
pub fn reportTestStart(this: TestReporterAgent, test_id: i32) void {
|
|
debug("reportTestStart", .{});
|
|
this.handle.?.reportTestStart(test_id);
|
|
}
|
|
|
|
/// Caller must ensure that it is enabled first.
|
|
pub fn reportTestEnd(this: TestReporterAgent, test_id: i32, bunTestStatus: TestStatus, elapsed: f64) void {
|
|
debug("reportTestEnd", .{});
|
|
this.handle.?.reportTestEnd(test_id, bunTestStatus, elapsed);
|
|
}
|
|
|
|
pub fn isEnabled(this: TestReporterAgent) bool {
|
|
return this.handle != null;
|
|
}
|
|
};
|
|
|
|
pub const LifecycleAgent = struct {
|
|
handle: ?*Handle = null,
|
|
const debug = Output.scoped(.LifecycleAgent, .visible);
|
|
|
|
pub const Handle = opaque {
|
|
extern "c" fn Bun__LifecycleAgentReportReload(agent: *Handle) void;
|
|
extern "c" fn Bun__LifecycleAgentReportError(agent: *Handle, exception: *ZigException) void;
|
|
extern "c" fn Bun__LifecycleAgentPreventExit(agent: *Handle) void;
|
|
extern "c" fn Bun__LifecycleAgentStopPreventingExit(agent: *Handle) void;
|
|
|
|
pub fn preventExit(this: *Handle) void {
|
|
Bun__LifecycleAgentPreventExit(this);
|
|
}
|
|
|
|
pub fn stopPreventingExit(this: *Handle) void {
|
|
Bun__LifecycleAgentStopPreventingExit(this);
|
|
}
|
|
|
|
pub fn reportReload(this: *Handle) void {
|
|
debug("reportReload", .{});
|
|
Bun__LifecycleAgentReportReload(this);
|
|
}
|
|
|
|
pub fn reportError(this: *Handle, exception: *ZigException) void {
|
|
debug("reportError", .{});
|
|
Bun__LifecycleAgentReportError(this, exception);
|
|
}
|
|
};
|
|
|
|
pub export fn Bun__LifecycleAgentEnable(agent: *Handle) void {
|
|
if (VirtualMachine.get().debugger) |*debugger| {
|
|
debug("enable", .{});
|
|
debugger.lifecycle_reporter_agent.handle = agent;
|
|
}
|
|
}
|
|
|
|
pub export fn Bun__LifecycleAgentDisable(agent: *Handle) void {
|
|
_ = agent; // autofix
|
|
if (VirtualMachine.get().debugger) |*debugger| {
|
|
debug("disable", .{});
|
|
debugger.lifecycle_reporter_agent.handle = null;
|
|
}
|
|
}
|
|
|
|
pub fn reportReload(this: *LifecycleAgent) void {
|
|
if (this.handle) |handle| {
|
|
handle.reportReload();
|
|
}
|
|
}
|
|
|
|
pub fn reportError(this: *LifecycleAgent, exception: *ZigException) void {
|
|
if (this.handle) |handle| {
|
|
handle.reportError(exception);
|
|
}
|
|
}
|
|
|
|
pub fn isEnabled(this: *const LifecycleAgent) bool {
|
|
return this.handle != null;
|
|
}
|
|
};
|
|
|
|
pub const DebuggerId = bun.GenericIndex(i32, Debugger);
|
|
pub const BunFrontendDevServerAgent = @import("./api/server/InspectorBunFrontendDevServerAgent.zig").BunFrontendDevServerAgent;
|
|
pub const HTTPServerAgent = @import("./bindings/HTTPServerAgent.zig");
|
|
|
|
const DotEnv = @import("../env_loader.zig");
|
|
const std = @import("std");
|
|
|
|
const bun = @import("bun");
|
|
const Environment = bun.Environment;
|
|
const Output = bun.Output;
|
|
const uv = bun.windows.libuv;
|
|
|
|
const jsc = bun.jsc;
|
|
const Debugger = jsc.Debugger;
|
|
const JSGlobalObject = jsc.JSGlobalObject;
|
|
const VirtualMachine = jsc.VirtualMachine;
|
|
const ZigException = jsc.ZigException;
|