diff options
Diffstat (limited to '')
| -rw-r--r-- | src/bun.js/api/bun.zig | 60 | ||||
| -rw-r--r-- | src/bun.js/api/server.classes.ts | 4 | ||||
| -rw-r--r-- | src/bun.js/api/server.zig | 108 | ||||
| -rw-r--r-- | src/bun.js/bindings/ZigGeneratedClasses.cpp | 144 | ||||
| -rw-r--r-- | src/bun.js/bindings/ZigGeneratedClasses.h | 4 | ||||
| -rw-r--r-- | src/bun.js/bindings/generated_classes.zig | 104 | ||||
| -rw-r--r-- | src/bun.js/javascript.zig | 8 | ||||
| -rw-r--r-- | src/bun.js/rare_data.zig | 62 | 
8 files changed, 473 insertions, 21 deletions
| diff --git a/src/bun.js/api/bun.zig b/src/bun.js/api/bun.zig index a9d7ed970..71b065993 100644 --- a/src/bun.js/api/bun.zig +++ b/src/bun.js/api/bun.zig @@ -2481,7 +2481,7 @@ pub fn serve(      callframe: *JSC.CallFrame,  ) callconv(.C) JSC.JSValue {      const arguments = callframe.arguments(2).slice(); -    const config: JSC.API.ServerConfig = brk: { +    var config: JSC.API.ServerConfig = brk: {          var exception_ = [1]JSC.JSValueRef{null};          var exception = &exception_; @@ -2497,6 +2497,40 @@ pub fn serve(      var exception_value: *JSC.JSValue = undefined; +    if (config.allow_hot) { +        if (globalObject.bunVM().hotMap()) |hot| { +            if (config.id.len == 0) { +                config.id = config.computeID(globalObject.allocator()); +            } + +            if (hot.getEntry(config.id)) |entry| { +                switch (entry.tag()) { +                    @field(@TypeOf(entry.tag()), @typeName(JSC.API.HTTPServer)) => { +                        var server: *JSC.API.HTTPServer = entry.as(JSC.API.HTTPServer); +                        server.onReloadFromZig(&config, globalObject); +                        return server.thisObject; +                    }, +                    @field(@TypeOf(entry.tag()), @typeName(JSC.API.DebugHTTPServer)) => { +                        var server: *JSC.API.DebugHTTPServer = entry.as(JSC.API.DebugHTTPServer); +                        server.onReloadFromZig(&config, globalObject); +                        return server.thisObject; +                    }, +                    @field(@TypeOf(entry.tag()), @typeName(JSC.API.DebugHTTPSServer)) => { +                        var server: *JSC.API.DebugHTTPSServer = entry.as(JSC.API.DebugHTTPSServer); +                        server.onReloadFromZig(&config, globalObject); +                        return server.thisObject; +                    }, +                    @field(@TypeOf(entry.tag()), @typeName(JSC.API.HTTPSServer)) => { +                        var server: *JSC.API.HTTPSServer = entry.as(JSC.API.HTTPSServer); +                        server.onReloadFromZig(&config, globalObject); +                        return server.thisObject; +                    }, +                    else => {}, +                } +            } +        } +    } +      // Listen happens on the next tick!      // This is so we can return a Server object      if (config.ssl_config != null) { @@ -2515,6 +2549,12 @@ pub fn serve(              obj.protect();              server.thisObject = obj; + +            if (config.allow_hot) { +                if (globalObject.bunVM().hotMap()) |hot| { +                    hot.insert(config.id, server); +                } +            }              return obj;          } else {              var server = JSC.API.HTTPSServer.init(config, globalObject.ptr()); @@ -2530,6 +2570,12 @@ pub fn serve(              const obj = server.toJS(globalObject);              obj.protect();              server.thisObject = obj; + +            if (config.allow_hot) { +                if (globalObject.bunVM().hotMap()) |hot| { +                    hot.insert(config.id, server); +                } +            }              return obj;          }      } else { @@ -2547,6 +2593,12 @@ pub fn serve(              const obj = server.toJS(globalObject);              obj.protect();              server.thisObject = obj; + +            if (config.allow_hot) { +                if (globalObject.bunVM().hotMap()) |hot| { +                    hot.insert(config.id, server); +                } +            }              return obj;          } else {              var server = JSC.API.HTTPServer.init(config, globalObject.ptr()); @@ -2563,6 +2615,12 @@ pub fn serve(              obj.protect();              server.thisObject = obj; + +            if (config.allow_hot) { +                if (globalObject.bunVM().hotMap()) |hot| { +                    hot.insert(config.id, server); +                } +            }              return obj;          }      } diff --git a/src/bun.js/api/server.classes.ts b/src/bun.js/api/server.classes.ts index 7db8a3444..544f37ce6 100644 --- a/src/bun.js/api/server.classes.ts +++ b/src/bun.js/api/server.classes.ts @@ -27,6 +27,10 @@ function generate(name) {        port: {          getter: "getPort",        }, +      id: { +        getter: "getId", +        cache: true, +      },        pendingRequests: {          getter: "getPendingRequests",        }, diff --git a/src/bun.js/api/server.zig b/src/bun.js/api/server.zig index 81a50a5a7..01f06ebf2 100644 --- a/src/bun.js/api/server.zig +++ b/src/bun.js/api/server.zig @@ -158,6 +158,36 @@ pub const ServerConfig = struct {      inspector: bool = false,      reuse_port: bool = false, +    id: []const u8 = "", +    allow_hot: bool = true, + +    pub fn computeID(this: *const ServerConfig, allocator: std.mem.Allocator) []const u8 { +        var arraylist = std.ArrayList(u8).init(allocator); +        var writer = arraylist.writer(); + +        writer.writeAll("[http]-") catch {}; +        switch (this.address) { +            .tcp => { +                if (this.address.tcp.hostname) |host| { +                    writer.print("tcp:{s}:{d}", .{ +                        bun.sliceTo(host, 0), +                        this.address.tcp.port, +                    }) catch {}; +                } else { +                    writer.print("tcp:localhost:{d}", .{ +                        this.address.tcp.port, +                    }) catch {}; +                } +            }, +            .unix => { +                writer.print("unix:{s}", .{ +                    bun.sliceTo(this.address.unix, 0), +                }) catch {}; +            }, +        } + +        return arraylist.items; +    }      pub const SSLConfig = struct {          server_name: [*c]const u8 = null, @@ -794,6 +824,23 @@ pub const ServerConfig = struct {                  }              } +            if (arg.get(global, "id")) |id| { +                if (id.isUndefinedOrNull()) { +                    args.allow_hot = false; +                } else { +                    const id_str = id.toSlice( +                        global, +                        bun.default_allocator, +                    ); + +                    if (id_str.len > 0) { +                        args.id = (id_str.cloneIfNeeded(bun.default_allocator) catch unreachable).slice(); +                    } else { +                        args.allow_hot = false; +                    } +                } +            } +              if (arg.get(global, "development")) |dev| {                  args.development = dev.coerce(bool, global);                  args.reuse_port = !args.development; @@ -4867,26 +4914,8 @@ pub fn NewServer(comptime NamespaceType: type, comptime ssl_enabled_: bool, comp              return JSC.jsBoolean(true);          } -        pub fn onReload( -            this: *ThisServer, -            globalThis: *JSC.JSGlobalObject, -            callframe: *JSC.CallFrame, -        ) callconv(.C) JSC.JSValue { -            const arguments = callframe.arguments(1).slice(); -            if (arguments.len < 1) { -                globalThis.throwNotEnoughArguments("reload", 1, 0); -                return .zero; -            } - -            var args_slice = JSC.Node.ArgumentsSlice.init(globalThis.bunVM(), arguments); -            defer args_slice.deinit(); -            var exception_ref = [_]JSC.C.JSValueRef{null}; -            var exception: JSC.C.ExceptionRef = &exception_ref; -            var new_config = ServerConfig.fromJS(globalThis, &args_slice, exception); -            if (exception.* != null) { -                globalThis.throwValue(exception_ref[0].?.value()); -                return .zero; -            } +        pub fn onReloadFromZig(this: *ThisServer, new_config: *ServerConfig, globalThis: *JSC.JSGlobalObject) void { +            httplog("onReload", .{});              // only reload those two              if (this.config.onRequest != new_config.onRequest) { @@ -4915,6 +4944,30 @@ pub fn NewServer(comptime NamespaceType: type, comptime ssl_enabled_: bool, comp                      this.config.websocket = ws.*;                  } // we don't remove it              } +        } + +        pub fn onReload( +            this: *ThisServer, +            globalThis: *JSC.JSGlobalObject, +            callframe: *JSC.CallFrame, +        ) callconv(.C) JSC.JSValue { +            const arguments = callframe.arguments(1).slice(); +            if (arguments.len < 1) { +                globalThis.throwNotEnoughArguments("reload", 1, 0); +                return .zero; +            } + +            var args_slice = JSC.Node.ArgumentsSlice.init(globalThis.bunVM(), arguments); +            defer args_slice.deinit(); +            var exception_ref = [_]JSC.C.JSValueRef{null}; +            var exception: JSC.C.ExceptionRef = &exception_ref; +            var new_config = ServerConfig.fromJS(globalThis, &args_slice, exception); +            if (exception.* != null) { +                globalThis.throwValue(exception_ref[0].?.value()); +                return .zero; +            } + +            this.onReloadFromZig(&new_config, globalThis);              return this.thisObject;          } @@ -5066,6 +5119,15 @@ pub fn NewServer(comptime NamespaceType: type, comptime ssl_enabled_: bool, comp              return JSC.JSValue.jsNumber(listener.getLocalPort());          } +        pub fn getId( +            this: *ThisServer, +            globalThis: *JSC.JSGlobalObject, +        ) callconv(.C) JSC.JSValue { +            var str = bun.String.create(this.config.id); +            defer str.deref(); +            return str.toJS(globalThis); +        } +          pub fn getPendingRequests(              this: *ThisServer,              _: *JSC.JSGlobalObject, @@ -5170,6 +5232,12 @@ pub fn NewServer(comptime NamespaceType: type, comptime ssl_enabled_: bool, comp          }          pub fn stop(this: *ThisServer, abrupt: bool) void { +            if (this.config.allow_hot and this.config.id.len > 0) { +                if (this.globalThis.bunVM().hotMap()) |hot| { +                    hot.remove(this.config.id); +                } +            } +              this.stopListening(abrupt);              this.deinitIfWeCan();          } diff --git a/src/bun.js/bindings/ZigGeneratedClasses.cpp b/src/bun.js/bindings/ZigGeneratedClasses.cpp index 0ab7a1b5d..497408632 100644 --- a/src/bun.js/bindings/ZigGeneratedClasses.cpp +++ b/src/bun.js/bindings/ZigGeneratedClasses.cpp @@ -4176,6 +4176,9 @@ JSC_DECLARE_HOST_FUNCTION(DebugHTTPSServerPrototype__fetchCallback);  extern "C" JSC::EncodedJSValue DebugHTTPSServerPrototype__getHostname(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject);  JSC_DECLARE_CUSTOM_GETTER(DebugHTTPSServerPrototype__hostnameGetterWrap); +extern "C" JSC::EncodedJSValue DebugHTTPSServerPrototype__getId(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject); +JSC_DECLARE_CUSTOM_GETTER(DebugHTTPSServerPrototype__idGetterWrap); +  extern "C" JSC::EncodedJSValue DebugHTTPSServerPrototype__getPendingRequests(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject);  JSC_DECLARE_CUSTOM_GETTER(DebugHTTPSServerPrototype__pendingRequestsGetterWrap); @@ -4206,6 +4209,7 @@ static const HashTableValue JSDebugHTTPSServerPrototypeTableValues[] = {      { "development"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, DebugHTTPSServerPrototype__developmentGetterWrap, 0 } },      { "fetch"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, DebugHTTPSServerPrototype__fetchCallback, 1 } },      { "hostname"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, DebugHTTPSServerPrototype__hostnameGetterWrap, 0 } }, +    { "id"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, DebugHTTPSServerPrototype__idGetterWrap, 0 } },      { "pendingRequests"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, DebugHTTPSServerPrototype__pendingRequestsGetterWrap, 0 } },      { "pendingWebSockets"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, DebugHTTPSServerPrototype__pendingWebSocketsGetterWrap, 0 } },      { "port"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, DebugHTTPSServerPrototype__portGetterWrap, 0 } }, @@ -4301,6 +4305,37 @@ extern "C" EncodedJSValue DebugHTTPSServerPrototype__hostnameGetCachedValue(JSC:      return JSValue::encode(thisObject->m_hostname.get());  } +JSC_DEFINE_CUSTOM_GETTER(DebugHTTPSServerPrototype__idGetterWrap, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ +    auto& vm = lexicalGlobalObject->vm(); +    Zig::GlobalObject* globalObject = reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject); +    auto throwScope = DECLARE_THROW_SCOPE(vm); +    JSDebugHTTPSServer* thisObject = jsCast<JSDebugHTTPSServer*>(JSValue::decode(thisValue)); +    JSC::EnsureStillAliveScope thisArg = JSC::EnsureStillAliveScope(thisObject); + +    if (JSValue cachedValue = thisObject->m_id.get()) +        return JSValue::encode(cachedValue); + +    JSC::JSValue result = JSC::JSValue::decode( +        DebugHTTPSServerPrototype__getId(thisObject->wrapped(), globalObject)); +    RETURN_IF_EXCEPTION(throwScope, {}); +    thisObject->m_id.set(vm, thisObject, result); +    RELEASE_AND_RETURN(throwScope, JSValue::encode(result)); +} + +extern "C" void DebugHTTPSServerPrototype__idSetCachedValue(JSC::EncodedJSValue thisValue, JSC::JSGlobalObject* globalObject, JSC::EncodedJSValue value) +{ +    auto& vm = globalObject->vm(); +    auto* thisObject = jsCast<JSDebugHTTPSServer*>(JSValue::decode(thisValue)); +    thisObject->m_id.set(vm, thisObject, JSValue::decode(value)); +} + +extern "C" EncodedJSValue DebugHTTPSServerPrototype__idGetCachedValue(JSC::EncodedJSValue thisValue) +{ +    auto* thisObject = jsCast<JSDebugHTTPSServer*>(JSValue::decode(thisValue)); +    return JSValue::encode(thisObject->m_id.get()); +} +  JSC_DEFINE_CUSTOM_GETTER(DebugHTTPSServerPrototype__pendingRequestsGetterWrap, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))  {      auto& vm = lexicalGlobalObject->vm(); @@ -4564,6 +4599,7 @@ void JSDebugHTTPSServer::visitAdditionalChildren(Visitor& visitor)      ASSERT_GC_OBJECT_INHERITS(thisObject, info());      visitor.append(thisObject->m_hostname); +    visitor.append(thisObject->m_id);  }  DEFINE_VISIT_ADDITIONAL_CHILDREN(JSDebugHTTPSServer); @@ -4622,6 +4658,9 @@ JSC_DECLARE_HOST_FUNCTION(DebugHTTPServerPrototype__fetchCallback);  extern "C" JSC::EncodedJSValue DebugHTTPServerPrototype__getHostname(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject);  JSC_DECLARE_CUSTOM_GETTER(DebugHTTPServerPrototype__hostnameGetterWrap); +extern "C" JSC::EncodedJSValue DebugHTTPServerPrototype__getId(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject); +JSC_DECLARE_CUSTOM_GETTER(DebugHTTPServerPrototype__idGetterWrap); +  extern "C" JSC::EncodedJSValue DebugHTTPServerPrototype__getPendingRequests(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject);  JSC_DECLARE_CUSTOM_GETTER(DebugHTTPServerPrototype__pendingRequestsGetterWrap); @@ -4652,6 +4691,7 @@ static const HashTableValue JSDebugHTTPServerPrototypeTableValues[] = {      { "development"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, DebugHTTPServerPrototype__developmentGetterWrap, 0 } },      { "fetch"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, DebugHTTPServerPrototype__fetchCallback, 1 } },      { "hostname"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, DebugHTTPServerPrototype__hostnameGetterWrap, 0 } }, +    { "id"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, DebugHTTPServerPrototype__idGetterWrap, 0 } },      { "pendingRequests"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, DebugHTTPServerPrototype__pendingRequestsGetterWrap, 0 } },      { "pendingWebSockets"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, DebugHTTPServerPrototype__pendingWebSocketsGetterWrap, 0 } },      { "port"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, DebugHTTPServerPrototype__portGetterWrap, 0 } }, @@ -4747,6 +4787,37 @@ extern "C" EncodedJSValue DebugHTTPServerPrototype__hostnameGetCachedValue(JSC::      return JSValue::encode(thisObject->m_hostname.get());  } +JSC_DEFINE_CUSTOM_GETTER(DebugHTTPServerPrototype__idGetterWrap, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ +    auto& vm = lexicalGlobalObject->vm(); +    Zig::GlobalObject* globalObject = reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject); +    auto throwScope = DECLARE_THROW_SCOPE(vm); +    JSDebugHTTPServer* thisObject = jsCast<JSDebugHTTPServer*>(JSValue::decode(thisValue)); +    JSC::EnsureStillAliveScope thisArg = JSC::EnsureStillAliveScope(thisObject); + +    if (JSValue cachedValue = thisObject->m_id.get()) +        return JSValue::encode(cachedValue); + +    JSC::JSValue result = JSC::JSValue::decode( +        DebugHTTPServerPrototype__getId(thisObject->wrapped(), globalObject)); +    RETURN_IF_EXCEPTION(throwScope, {}); +    thisObject->m_id.set(vm, thisObject, result); +    RELEASE_AND_RETURN(throwScope, JSValue::encode(result)); +} + +extern "C" void DebugHTTPServerPrototype__idSetCachedValue(JSC::EncodedJSValue thisValue, JSC::JSGlobalObject* globalObject, JSC::EncodedJSValue value) +{ +    auto& vm = globalObject->vm(); +    auto* thisObject = jsCast<JSDebugHTTPServer*>(JSValue::decode(thisValue)); +    thisObject->m_id.set(vm, thisObject, JSValue::decode(value)); +} + +extern "C" EncodedJSValue DebugHTTPServerPrototype__idGetCachedValue(JSC::EncodedJSValue thisValue) +{ +    auto* thisObject = jsCast<JSDebugHTTPServer*>(JSValue::decode(thisValue)); +    return JSValue::encode(thisObject->m_id.get()); +} +  JSC_DEFINE_CUSTOM_GETTER(DebugHTTPServerPrototype__pendingRequestsGetterWrap, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))  {      auto& vm = lexicalGlobalObject->vm(); @@ -5010,6 +5081,7 @@ void JSDebugHTTPServer::visitAdditionalChildren(Visitor& visitor)      ASSERT_GC_OBJECT_INHERITS(thisObject, info());      visitor.append(thisObject->m_hostname); +    visitor.append(thisObject->m_id);  }  DEFINE_VISIT_ADDITIONAL_CHILDREN(JSDebugHTTPServer); @@ -11359,6 +11431,9 @@ JSC_DECLARE_HOST_FUNCTION(HTTPSServerPrototype__fetchCallback);  extern "C" JSC::EncodedJSValue HTTPSServerPrototype__getHostname(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject);  JSC_DECLARE_CUSTOM_GETTER(HTTPSServerPrototype__hostnameGetterWrap); +extern "C" JSC::EncodedJSValue HTTPSServerPrototype__getId(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject); +JSC_DECLARE_CUSTOM_GETTER(HTTPSServerPrototype__idGetterWrap); +  extern "C" JSC::EncodedJSValue HTTPSServerPrototype__getPendingRequests(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject);  JSC_DECLARE_CUSTOM_GETTER(HTTPSServerPrototype__pendingRequestsGetterWrap); @@ -11389,6 +11464,7 @@ static const HashTableValue JSHTTPSServerPrototypeTableValues[] = {      { "development"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, HTTPSServerPrototype__developmentGetterWrap, 0 } },      { "fetch"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, HTTPSServerPrototype__fetchCallback, 1 } },      { "hostname"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, HTTPSServerPrototype__hostnameGetterWrap, 0 } }, +    { "id"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, HTTPSServerPrototype__idGetterWrap, 0 } },      { "pendingRequests"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, HTTPSServerPrototype__pendingRequestsGetterWrap, 0 } },      { "pendingWebSockets"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, HTTPSServerPrototype__pendingWebSocketsGetterWrap, 0 } },      { "port"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, HTTPSServerPrototype__portGetterWrap, 0 } }, @@ -11484,6 +11560,37 @@ extern "C" EncodedJSValue HTTPSServerPrototype__hostnameGetCachedValue(JSC::Enco      return JSValue::encode(thisObject->m_hostname.get());  } +JSC_DEFINE_CUSTOM_GETTER(HTTPSServerPrototype__idGetterWrap, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ +    auto& vm = lexicalGlobalObject->vm(); +    Zig::GlobalObject* globalObject = reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject); +    auto throwScope = DECLARE_THROW_SCOPE(vm); +    JSHTTPSServer* thisObject = jsCast<JSHTTPSServer*>(JSValue::decode(thisValue)); +    JSC::EnsureStillAliveScope thisArg = JSC::EnsureStillAliveScope(thisObject); + +    if (JSValue cachedValue = thisObject->m_id.get()) +        return JSValue::encode(cachedValue); + +    JSC::JSValue result = JSC::JSValue::decode( +        HTTPSServerPrototype__getId(thisObject->wrapped(), globalObject)); +    RETURN_IF_EXCEPTION(throwScope, {}); +    thisObject->m_id.set(vm, thisObject, result); +    RELEASE_AND_RETURN(throwScope, JSValue::encode(result)); +} + +extern "C" void HTTPSServerPrototype__idSetCachedValue(JSC::EncodedJSValue thisValue, JSC::JSGlobalObject* globalObject, JSC::EncodedJSValue value) +{ +    auto& vm = globalObject->vm(); +    auto* thisObject = jsCast<JSHTTPSServer*>(JSValue::decode(thisValue)); +    thisObject->m_id.set(vm, thisObject, JSValue::decode(value)); +} + +extern "C" EncodedJSValue HTTPSServerPrototype__idGetCachedValue(JSC::EncodedJSValue thisValue) +{ +    auto* thisObject = jsCast<JSHTTPSServer*>(JSValue::decode(thisValue)); +    return JSValue::encode(thisObject->m_id.get()); +} +  JSC_DEFINE_CUSTOM_GETTER(HTTPSServerPrototype__pendingRequestsGetterWrap, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))  {      auto& vm = lexicalGlobalObject->vm(); @@ -11747,6 +11854,7 @@ void JSHTTPSServer::visitAdditionalChildren(Visitor& visitor)      ASSERT_GC_OBJECT_INHERITS(thisObject, info());      visitor.append(thisObject->m_hostname); +    visitor.append(thisObject->m_id);  }  DEFINE_VISIT_ADDITIONAL_CHILDREN(JSHTTPSServer); @@ -11805,6 +11913,9 @@ JSC_DECLARE_HOST_FUNCTION(HTTPServerPrototype__fetchCallback);  extern "C" JSC::EncodedJSValue HTTPServerPrototype__getHostname(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject);  JSC_DECLARE_CUSTOM_GETTER(HTTPServerPrototype__hostnameGetterWrap); +extern "C" JSC::EncodedJSValue HTTPServerPrototype__getId(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject); +JSC_DECLARE_CUSTOM_GETTER(HTTPServerPrototype__idGetterWrap); +  extern "C" JSC::EncodedJSValue HTTPServerPrototype__getPendingRequests(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject);  JSC_DECLARE_CUSTOM_GETTER(HTTPServerPrototype__pendingRequestsGetterWrap); @@ -11835,6 +11946,7 @@ static const HashTableValue JSHTTPServerPrototypeTableValues[] = {      { "development"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, HTTPServerPrototype__developmentGetterWrap, 0 } },      { "fetch"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, HTTPServerPrototype__fetchCallback, 1 } },      { "hostname"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, HTTPServerPrototype__hostnameGetterWrap, 0 } }, +    { "id"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, HTTPServerPrototype__idGetterWrap, 0 } },      { "pendingRequests"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, HTTPServerPrototype__pendingRequestsGetterWrap, 0 } },      { "pendingWebSockets"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, HTTPServerPrototype__pendingWebSocketsGetterWrap, 0 } },      { "port"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, HTTPServerPrototype__portGetterWrap, 0 } }, @@ -11930,6 +12042,37 @@ extern "C" EncodedJSValue HTTPServerPrototype__hostnameGetCachedValue(JSC::Encod      return JSValue::encode(thisObject->m_hostname.get());  } +JSC_DEFINE_CUSTOM_GETTER(HTTPServerPrototype__idGetterWrap, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ +    auto& vm = lexicalGlobalObject->vm(); +    Zig::GlobalObject* globalObject = reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject); +    auto throwScope = DECLARE_THROW_SCOPE(vm); +    JSHTTPServer* thisObject = jsCast<JSHTTPServer*>(JSValue::decode(thisValue)); +    JSC::EnsureStillAliveScope thisArg = JSC::EnsureStillAliveScope(thisObject); + +    if (JSValue cachedValue = thisObject->m_id.get()) +        return JSValue::encode(cachedValue); + +    JSC::JSValue result = JSC::JSValue::decode( +        HTTPServerPrototype__getId(thisObject->wrapped(), globalObject)); +    RETURN_IF_EXCEPTION(throwScope, {}); +    thisObject->m_id.set(vm, thisObject, result); +    RELEASE_AND_RETURN(throwScope, JSValue::encode(result)); +} + +extern "C" void HTTPServerPrototype__idSetCachedValue(JSC::EncodedJSValue thisValue, JSC::JSGlobalObject* globalObject, JSC::EncodedJSValue value) +{ +    auto& vm = globalObject->vm(); +    auto* thisObject = jsCast<JSHTTPServer*>(JSValue::decode(thisValue)); +    thisObject->m_id.set(vm, thisObject, JSValue::decode(value)); +} + +extern "C" EncodedJSValue HTTPServerPrototype__idGetCachedValue(JSC::EncodedJSValue thisValue) +{ +    auto* thisObject = jsCast<JSHTTPServer*>(JSValue::decode(thisValue)); +    return JSValue::encode(thisObject->m_id.get()); +} +  JSC_DEFINE_CUSTOM_GETTER(HTTPServerPrototype__pendingRequestsGetterWrap, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))  {      auto& vm = lexicalGlobalObject->vm(); @@ -12193,6 +12336,7 @@ void JSHTTPServer::visitAdditionalChildren(Visitor& visitor)      ASSERT_GC_OBJECT_INHERITS(thisObject, info());      visitor.append(thisObject->m_hostname); +    visitor.append(thisObject->m_id);  }  DEFINE_VISIT_ADDITIONAL_CHILDREN(JSHTTPServer); diff --git a/src/bun.js/bindings/ZigGeneratedClasses.h b/src/bun.js/bindings/ZigGeneratedClasses.h index b8b694068..e0b10ff55 100644 --- a/src/bun.js/bindings/ZigGeneratedClasses.h +++ b/src/bun.js/bindings/ZigGeneratedClasses.h @@ -511,6 +511,7 @@ public:      DECLARE_VISIT_OUTPUT_CONSTRAINTS;      mutable JSC::WriteBarrier<JSC::Unknown> m_hostname; +    mutable JSC::WriteBarrier<JSC::Unknown> m_id;  };  class JSDebugHTTPServer final : public JSC::JSDestructibleObject { @@ -567,6 +568,7 @@ public:      DECLARE_VISIT_OUTPUT_CONSTRAINTS;      mutable JSC::WriteBarrier<JSC::Unknown> m_hostname; +    mutable JSC::WriteBarrier<JSC::Unknown> m_id;  };  class JSDirent final : public JSC::JSDestructibleObject { @@ -1415,6 +1417,7 @@ public:      DECLARE_VISIT_OUTPUT_CONSTRAINTS;      mutable JSC::WriteBarrier<JSC::Unknown> m_hostname; +    mutable JSC::WriteBarrier<JSC::Unknown> m_id;  };  class JSHTTPServer final : public JSC::JSDestructibleObject { @@ -1471,6 +1474,7 @@ public:      DECLARE_VISIT_OUTPUT_CONSTRAINTS;      mutable JSC::WriteBarrier<JSC::Unknown> m_hostname; +    mutable JSC::WriteBarrier<JSC::Unknown> m_id;  };  class JSListener final : public JSC::JSDestructibleObject { diff --git a/src/bun.js/bindings/generated_classes.zig b/src/bun.js/bindings/generated_classes.zig index e98b8f973..116947c24 100644 --- a/src/bun.js/bindings/generated_classes.zig +++ b/src/bun.js/bindings/generated_classes.zig @@ -1242,6 +1242,28 @@ pub const JSDebugHTTPSServer = struct {          return result;      } +    extern fn DebugHTTPSServerPrototype__idSetCachedValue(JSC.JSValue, *JSC.JSGlobalObject, JSC.JSValue) void; + +    extern fn DebugHTTPSServerPrototype__idGetCachedValue(JSC.JSValue) JSC.JSValue; + +    /// `DebugHTTPSServer.id` setter +    /// This value will be visited by the garbage collector. +    pub fn idSetCached(thisValue: JSC.JSValue, globalObject: *JSC.JSGlobalObject, value: JSC.JSValue) void { +        JSC.markBinding(@src()); +        DebugHTTPSServerPrototype__idSetCachedValue(thisValue, globalObject, value); +    } + +    /// `DebugHTTPSServer.id` getter +    /// This value will be visited by the garbage collector. +    pub fn idGetCached(thisValue: JSC.JSValue) ?JSC.JSValue { +        JSC.markBinding(@src()); +        const result = DebugHTTPSServerPrototype__idGetCachedValue(thisValue); +        if (result == .zero) +            return null; + +        return result; +    } +      /// Create a new instance of DebugHTTPSServer      pub fn toJS(this: *DebugHTTPSServer, globalObject: *JSC.JSGlobalObject) JSC.JSValue {          JSC.markBinding(@src()); @@ -1286,6 +1308,9 @@ pub const JSDebugHTTPSServer = struct {          if (@TypeOf(DebugHTTPSServer.getHostname) != GetterType)              @compileLog("Expected DebugHTTPSServer.getHostname to be a getter"); +        if (@TypeOf(DebugHTTPSServer.getId) != GetterType) +            @compileLog("Expected DebugHTTPSServer.getId to be a getter"); +          if (@TypeOf(DebugHTTPSServer.getPendingRequests) != GetterType)              @compileLog("Expected DebugHTTPSServer.getPendingRequests to be a getter"); @@ -1315,6 +1340,7 @@ pub const JSDebugHTTPSServer = struct {              @export(DebugHTTPSServer.finalize, .{ .name = "DebugHTTPSServerClass__finalize" });              @export(DebugHTTPSServer.getDevelopment, .{ .name = "DebugHTTPSServerPrototype__getDevelopment" });              @export(DebugHTTPSServer.getHostname, .{ .name = "DebugHTTPSServerPrototype__getHostname" }); +            @export(DebugHTTPSServer.getId, .{ .name = "DebugHTTPSServerPrototype__getId" });              @export(DebugHTTPSServer.getPendingRequests, .{ .name = "DebugHTTPSServerPrototype__getPendingRequests" });              @export(DebugHTTPSServer.getPendingWebSockets, .{ .name = "DebugHTTPSServerPrototype__getPendingWebSockets" });              @export(DebugHTTPSServer.getPort, .{ .name = "DebugHTTPSServerPrototype__getPort" }); @@ -1359,6 +1385,28 @@ pub const JSDebugHTTPServer = struct {          return result;      } +    extern fn DebugHTTPServerPrototype__idSetCachedValue(JSC.JSValue, *JSC.JSGlobalObject, JSC.JSValue) void; + +    extern fn DebugHTTPServerPrototype__idGetCachedValue(JSC.JSValue) JSC.JSValue; + +    /// `DebugHTTPServer.id` setter +    /// This value will be visited by the garbage collector. +    pub fn idSetCached(thisValue: JSC.JSValue, globalObject: *JSC.JSGlobalObject, value: JSC.JSValue) void { +        JSC.markBinding(@src()); +        DebugHTTPServerPrototype__idSetCachedValue(thisValue, globalObject, value); +    } + +    /// `DebugHTTPServer.id` getter +    /// This value will be visited by the garbage collector. +    pub fn idGetCached(thisValue: JSC.JSValue) ?JSC.JSValue { +        JSC.markBinding(@src()); +        const result = DebugHTTPServerPrototype__idGetCachedValue(thisValue); +        if (result == .zero) +            return null; + +        return result; +    } +      /// Create a new instance of DebugHTTPServer      pub fn toJS(this: *DebugHTTPServer, globalObject: *JSC.JSGlobalObject) JSC.JSValue {          JSC.markBinding(@src()); @@ -1403,6 +1451,9 @@ pub const JSDebugHTTPServer = struct {          if (@TypeOf(DebugHTTPServer.getHostname) != GetterType)              @compileLog("Expected DebugHTTPServer.getHostname to be a getter"); +        if (@TypeOf(DebugHTTPServer.getId) != GetterType) +            @compileLog("Expected DebugHTTPServer.getId to be a getter"); +          if (@TypeOf(DebugHTTPServer.getPendingRequests) != GetterType)              @compileLog("Expected DebugHTTPServer.getPendingRequests to be a getter"); @@ -1432,6 +1483,7 @@ pub const JSDebugHTTPServer = struct {              @export(DebugHTTPServer.finalize, .{ .name = "DebugHTTPServerClass__finalize" });              @export(DebugHTTPServer.getDevelopment, .{ .name = "DebugHTTPServerPrototype__getDevelopment" });              @export(DebugHTTPServer.getHostname, .{ .name = "DebugHTTPServerPrototype__getHostname" }); +            @export(DebugHTTPServer.getId, .{ .name = "DebugHTTPServerPrototype__getId" });              @export(DebugHTTPServer.getPendingRequests, .{ .name = "DebugHTTPServerPrototype__getPendingRequests" });              @export(DebugHTTPServer.getPendingWebSockets, .{ .name = "DebugHTTPServerPrototype__getPendingWebSockets" });              @export(DebugHTTPServer.getPort, .{ .name = "DebugHTTPServerPrototype__getPort" }); @@ -3059,6 +3111,28 @@ pub const JSHTTPSServer = struct {          return result;      } +    extern fn HTTPSServerPrototype__idSetCachedValue(JSC.JSValue, *JSC.JSGlobalObject, JSC.JSValue) void; + +    extern fn HTTPSServerPrototype__idGetCachedValue(JSC.JSValue) JSC.JSValue; + +    /// `HTTPSServer.id` setter +    /// This value will be visited by the garbage collector. +    pub fn idSetCached(thisValue: JSC.JSValue, globalObject: *JSC.JSGlobalObject, value: JSC.JSValue) void { +        JSC.markBinding(@src()); +        HTTPSServerPrototype__idSetCachedValue(thisValue, globalObject, value); +    } + +    /// `HTTPSServer.id` getter +    /// This value will be visited by the garbage collector. +    pub fn idGetCached(thisValue: JSC.JSValue) ?JSC.JSValue { +        JSC.markBinding(@src()); +        const result = HTTPSServerPrototype__idGetCachedValue(thisValue); +        if (result == .zero) +            return null; + +        return result; +    } +      /// Create a new instance of HTTPSServer      pub fn toJS(this: *HTTPSServer, globalObject: *JSC.JSGlobalObject) JSC.JSValue {          JSC.markBinding(@src()); @@ -3103,6 +3177,9 @@ pub const JSHTTPSServer = struct {          if (@TypeOf(HTTPSServer.getHostname) != GetterType)              @compileLog("Expected HTTPSServer.getHostname to be a getter"); +        if (@TypeOf(HTTPSServer.getId) != GetterType) +            @compileLog("Expected HTTPSServer.getId to be a getter"); +          if (@TypeOf(HTTPSServer.getPendingRequests) != GetterType)              @compileLog("Expected HTTPSServer.getPendingRequests to be a getter"); @@ -3132,6 +3209,7 @@ pub const JSHTTPSServer = struct {              @export(HTTPSServer.finalize, .{ .name = "HTTPSServerClass__finalize" });              @export(HTTPSServer.getDevelopment, .{ .name = "HTTPSServerPrototype__getDevelopment" });              @export(HTTPSServer.getHostname, .{ .name = "HTTPSServerPrototype__getHostname" }); +            @export(HTTPSServer.getId, .{ .name = "HTTPSServerPrototype__getId" });              @export(HTTPSServer.getPendingRequests, .{ .name = "HTTPSServerPrototype__getPendingRequests" });              @export(HTTPSServer.getPendingWebSockets, .{ .name = "HTTPSServerPrototype__getPendingWebSockets" });              @export(HTTPSServer.getPort, .{ .name = "HTTPSServerPrototype__getPort" }); @@ -3176,6 +3254,28 @@ pub const JSHTTPServer = struct {          return result;      } +    extern fn HTTPServerPrototype__idSetCachedValue(JSC.JSValue, *JSC.JSGlobalObject, JSC.JSValue) void; + +    extern fn HTTPServerPrototype__idGetCachedValue(JSC.JSValue) JSC.JSValue; + +    /// `HTTPServer.id` setter +    /// This value will be visited by the garbage collector. +    pub fn idSetCached(thisValue: JSC.JSValue, globalObject: *JSC.JSGlobalObject, value: JSC.JSValue) void { +        JSC.markBinding(@src()); +        HTTPServerPrototype__idSetCachedValue(thisValue, globalObject, value); +    } + +    /// `HTTPServer.id` getter +    /// This value will be visited by the garbage collector. +    pub fn idGetCached(thisValue: JSC.JSValue) ?JSC.JSValue { +        JSC.markBinding(@src()); +        const result = HTTPServerPrototype__idGetCachedValue(thisValue); +        if (result == .zero) +            return null; + +        return result; +    } +      /// Create a new instance of HTTPServer      pub fn toJS(this: *HTTPServer, globalObject: *JSC.JSGlobalObject) JSC.JSValue {          JSC.markBinding(@src()); @@ -3220,6 +3320,9 @@ pub const JSHTTPServer = struct {          if (@TypeOf(HTTPServer.getHostname) != GetterType)              @compileLog("Expected HTTPServer.getHostname to be a getter"); +        if (@TypeOf(HTTPServer.getId) != GetterType) +            @compileLog("Expected HTTPServer.getId to be a getter"); +          if (@TypeOf(HTTPServer.getPendingRequests) != GetterType)              @compileLog("Expected HTTPServer.getPendingRequests to be a getter"); @@ -3249,6 +3352,7 @@ pub const JSHTTPServer = struct {              @export(HTTPServer.finalize, .{ .name = "HTTPServerClass__finalize" });              @export(HTTPServer.getDevelopment, .{ .name = "HTTPServerPrototype__getDevelopment" });              @export(HTTPServer.getHostname, .{ .name = "HTTPServerPrototype__getHostname" }); +            @export(HTTPServer.getId, .{ .name = "HTTPServerPrototype__getId" });              @export(HTTPServer.getPendingRequests, .{ .name = "HTTPServerPrototype__getPendingRequests" });              @export(HTTPServer.getPendingWebSockets, .{ .name = "HTTPServerPrototype__getPendingWebSockets" });              @export(HTTPServer.getPort, .{ .name = "HTTPServerPrototype__getPort" }); diff --git a/src/bun.js/javascript.zig b/src/bun.js/javascript.zig index 01f6383af..fc2bd7a05 100644 --- a/src/bun.js/javascript.zig +++ b/src/bun.js/javascript.zig @@ -766,6 +766,14 @@ pub const VirtualMachine = struct {          return debugger.next_debugger_id;      } +    pub fn hotMap(this: *VirtualMachine) ?*JSC.RareData.HotMap { +        if (this.hot_reload != .hot) { +            return null; +        } + +        return this.rareData().hotMap(this.allocator); +    } +      pub var has_created_debugger: bool = false;      pub const Debugger = struct { diff --git a/src/bun.js/rare_data.zig b/src/bun.js/rare_data.zig index 216b56eda..ab9cc9ea4 100644 --- a/src/bun.js/rare_data.zig +++ b/src/bun.js/rare_data.zig @@ -19,6 +19,8 @@ stdout_store: ?*Blob.Store = null,  entropy_cache: ?*EntropyCache = null, +hot_map: ?HotMap = null, +  // TODO: make this per JSGlobalObject instead of global  // This does not handle ShadowRealm correctly!  tail_cleanup_hook: ?*CleanupHook = null, @@ -30,6 +32,14 @@ global_dns_data: ?*JSC.DNS.GlobalData = null,  mime_types: ?bun.HTTP.MimeType.Map = null, +pub fn hotMap(this: *RareData, allocator: std.mem.Allocator) *HotMap { +    if (this.hot_map == null) { +        this.hot_map = HotMap.init(allocator); +    } + +    return &this.hot_map.?; +} +  pub fn mimeTypeFromString(this: *RareData, allocator: std.mem.Allocator, str: []const u8) ?bun.HTTP.MimeType {      if (this.mime_types == null) {          this.mime_types = bun.HTTP.MimeType.createHashTable( @@ -40,6 +50,58 @@ pub fn mimeTypeFromString(this: *RareData, allocator: std.mem.Allocator, str: []      return this.mime_types.?.get(str);  } +pub const HotMap = struct { +    _map: bun.StringArrayHashMap(Entry), + +    const HTTPServer = JSC.API.HTTPServer; +    const HTTPSServer = JSC.API.HTTPSServer; +    const DebugHTTPServer = JSC.API.DebugHTTPServer; +    const DebugHTTPSServer = JSC.API.DebugHTTPSServer; +    const TCPSocket = JSC.API.TCPSocket; +    const TLSSocket = JSC.API.TLSSocket; +    const Listener = JSC.API.Listener; +    const Entry = bun.TaggedPointerUnion(.{ +        HTTPServer, +        HTTPSServer, +        DebugHTTPServer, +        DebugHTTPSServer, +        TCPSocket, +        TLSSocket, +        Listener, +    }); + +    pub fn init(allocator: std.mem.Allocator) HotMap { +        return .{ +            ._map = bun.StringArrayHashMap(Entry).init(allocator), +        }; +    } + +    pub fn get(this: *HotMap, key: []const u8, comptime Type: type) ?*Type { +        var entry = this._map.get(key) orelse return null; +        return entry.get(Type); +    } + +    pub fn getEntry(this: *HotMap, key: []const u8) ?Entry { +        return this._map.get(key) orelse return null; +    } + +    pub fn insert(this: *HotMap, key: []const u8, ptr: anytype) void { +        var entry = this._map.getOrPut(key) catch @panic("Out of memory"); +        if (entry.found_existing) { +            @panic("HotMap already contains key"); +        } + +        entry.key_ptr.* = this._map.allocator.dupe(u8, key) catch @panic("Out of memory"); +        entry.value_ptr.* = Entry.init(ptr); +    } + +    pub fn remove(this: *HotMap, key: []const u8) void { +        var entry = this._map.getEntry(key) orelse return; +        bun.default_allocator.free(entry.key_ptr.*); +        _ = this._map.orderedRemove(key); +    } +}; +  pub fn filePolls(this: *RareData, vm: *JSC.VirtualMachine) *JSC.FilePoll.HiveArray {      return this.file_polls_ orelse {          this.file_polls_ = vm.allocator.create(JSC.FilePoll.HiveArray) catch unreachable; | 
