@noxfly/noxus 2.4.0 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/main.js CHANGED
@@ -69,7 +69,6 @@ __export(main_exports, {
69
69
  NotFoundException: () => NotFoundException,
70
70
  NotImplementedException: () => NotImplementedException,
71
71
  NoxApp: () => NoxApp,
72
- NoxRendererClient: () => NoxRendererClient,
73
72
  NoxSocket: () => NoxSocket,
74
73
  Patch: () => Patch,
75
74
  PaymentRequiredException: () => PaymentRequiredException,
@@ -77,7 +76,6 @@ __export(main_exports, {
77
76
  Put: () => Put,
78
77
  RENDERER_EVENT_TYPE: () => RENDERER_EVENT_TYPE,
79
78
  ROUTE_METADATA_KEY: () => ROUTE_METADATA_KEY,
80
- RendererEventRegistry: () => RendererEventRegistry,
81
79
  Request: () => Request,
82
80
  RequestTimeoutException: () => RequestTimeoutException,
83
81
  ResponseException: () => ResponseException,
@@ -91,7 +89,6 @@ __export(main_exports, {
91
89
  VariantAlsoNegotiatesException: () => VariantAlsoNegotiatesException,
92
90
  bootstrapApplication: () => bootstrapApplication,
93
91
  createRendererEventMessage: () => createRendererEventMessage,
94
- exposeNoxusBridge: () => exposeNoxusBridge,
95
92
  forwardRef: () => forwardRef,
96
93
  getControllerMetadata: () => getControllerMetadata,
97
94
  getGuardForController: () => getGuardForController,
@@ -828,12 +825,17 @@ var _InjectorExplorer = class _InjectorExplorer {
828
825
  * Enqueues a class for deferred registration.
829
826
  * Called by the @Injectable decorator at import time.
830
827
  *
831
- * If {@link processPending} has already been called (i.e. after bootstrap),
832
- * the class is registered immediately so that late dynamic imports
833
- * (e.g. middlewares loaded after bootstrap) work correctly.
828
+ * If {@link processPending} has already been called (i.e. after bootstrap)
829
+ * and accumulation mode is not active, the class is registered immediately
830
+ * so that late dynamic imports (e.g. middlewares loaded after bootstrap)
831
+ * work correctly.
832
+ *
833
+ * When accumulation mode is active (between {@link beginAccumulate} and
834
+ * {@link flushAccumulated}), classes are queued instead — preserving the
835
+ * two-phase binding/resolution guarantee for lazy-loaded modules.
834
836
  */
835
837
  static enqueue(target, lifetime) {
836
- if (_InjectorExplorer.processed) {
838
+ if (_InjectorExplorer.processed && !_InjectorExplorer.accumulating) {
837
839
  _InjectorExplorer.registerImmediate(target, lifetime);
838
840
  return;
839
841
  }
@@ -842,6 +844,40 @@ var _InjectorExplorer = class _InjectorExplorer {
842
844
  lifetime
843
845
  });
844
846
  }
847
+ /**
848
+ * Enters accumulation mode. While active, all decorated classes discovered
849
+ * via dynamic imports are queued in {@link pending} rather than registered
850
+ * immediately. Call {@link flushAccumulated} to process them with the
851
+ * full two-phase (bind-then-resolve) guarantee.
852
+ */
853
+ static beginAccumulate() {
854
+ _InjectorExplorer.accumulating = true;
855
+ }
856
+ /**
857
+ * Exits accumulation mode and processes every class queued since
858
+ * {@link beginAccumulate} was called. Uses the same two-phase strategy
859
+ * as {@link processPending} (register all bindings first, then resolve
860
+ * singletons / controllers) so import ordering within a lazy batch
861
+ * does not cause resolution failures.
862
+ */
863
+ static flushAccumulated() {
864
+ _InjectorExplorer.accumulating = false;
865
+ const queue = [
866
+ ..._InjectorExplorer.pending
867
+ ];
868
+ _InjectorExplorer.pending.length = 0;
869
+ for (const { target, lifetime } of queue) {
870
+ if (!RootInjector.bindings.has(target)) {
871
+ RootInjector.bindings.set(target, {
872
+ implementation: target,
873
+ lifetime
874
+ });
875
+ }
876
+ }
877
+ for (const { target, lifetime } of queue) {
878
+ _InjectorExplorer.processRegistration(target, lifetime);
879
+ }
880
+ }
845
881
  /**
846
882
  * Processes all pending registrations in two phases:
847
883
  * 1. Register all bindings (no instantiation) so every dependency is known.
@@ -909,6 +945,7 @@ var _InjectorExplorer = class _InjectorExplorer {
909
945
  __name(_InjectorExplorer, "InjectorExplorer");
910
946
  __publicField(_InjectorExplorer, "pending", []);
911
947
  __publicField(_InjectorExplorer, "processed", false);
948
+ __publicField(_InjectorExplorer, "accumulating", false);
912
949
  var InjectorExplorer = _InjectorExplorer;
913
950
 
914
951
  // src/decorators/injectable.decorator.ts
@@ -1193,6 +1230,7 @@ var _Router = class _Router {
1193
1230
  constructor() {
1194
1231
  __publicField(this, "routes", new RadixTree());
1195
1232
  __publicField(this, "rootMiddlewares", []);
1233
+ __publicField(this, "lazyRoutes", /* @__PURE__ */ new Map());
1196
1234
  }
1197
1235
  /**
1198
1236
  * Registers a controller class with the router.
@@ -1240,6 +1278,24 @@ var _Router = class _Router {
1240
1278
  Logger.log(`Mapped ${controllerClass.name}${controllerGuardsInfo} controller's routes`);
1241
1279
  return this;
1242
1280
  }
1281
+ /**
1282
+ * Registers a lazy route. The module behind this route prefix will only
1283
+ * be imported (and its controllers/services registered in DI) the first
1284
+ * time a request targets this prefix.
1285
+ *
1286
+ * @param pathPrefix - Route prefix (e.g. "auth"). Matched against the first segment of the request path.
1287
+ * @param loadModule - A function that returns a dynamic import promise.
1288
+ */
1289
+ registerLazyRoute(pathPrefix, loadModule) {
1290
+ const normalized = pathPrefix.replace(/^\/+|\/+$/g, "");
1291
+ this.lazyRoutes.set(normalized, {
1292
+ loadModule,
1293
+ loading: null,
1294
+ loaded: false
1295
+ });
1296
+ Logger.log(`Registered lazy route prefix {${normalized}}`);
1297
+ return this;
1298
+ }
1243
1299
  /**
1244
1300
  * Defines a middleware for the root of the application.
1245
1301
  * This method allows you to register a middleware that will be applied to all requests
@@ -1272,7 +1328,7 @@ var _Router = class _Router {
1272
1328
  };
1273
1329
  let isCritical = false;
1274
1330
  try {
1275
- const routeDef = this.findRoute(request);
1331
+ const routeDef = await this.findRoute(request);
1276
1332
  await this.resolveController(request, response, routeDef);
1277
1333
  if (response.status > 400) {
1278
1334
  throw new ResponseException(response.status, response.error);
@@ -1430,16 +1486,62 @@ var _Router = class _Router {
1430
1486
  * @param request - The Request object containing the method and path to search for.
1431
1487
  * @returns The IRouteDefinition for the matched route.
1432
1488
  */
1433
- findRoute(request) {
1489
+ /**
1490
+ * Attempts to find a route definition for the given request.
1491
+ * Returns undefined instead of throwing when the route is not found,
1492
+ * so the caller can try lazy-loading first.
1493
+ */
1494
+ tryFindRoute(request) {
1434
1495
  const matchedRoutes = this.routes.search(request.path);
1435
1496
  if (matchedRoutes?.node === void 0 || matchedRoutes.node.children.length === 0) {
1436
- throw new NotFoundException(`No route matches ${request.method} ${request.path}`);
1497
+ return void 0;
1437
1498
  }
1438
1499
  const routeDef = matchedRoutes.node.findExactChild(request.method);
1439
- if (routeDef?.value === void 0) {
1440
- throw new MethodNotAllowedException(`Method Not Allowed for ${request.method} ${request.path}`);
1500
+ return routeDef?.value;
1501
+ }
1502
+ /**
1503
+ * Finds the route definition for a given request.
1504
+ * If no eagerly-registered route matches, attempts to load a lazy module
1505
+ * whose prefix matches the request path, then retries.
1506
+ */
1507
+ async findRoute(request) {
1508
+ const direct = this.tryFindRoute(request);
1509
+ if (direct) return direct;
1510
+ await this.tryLoadLazyRoute(request.path);
1511
+ const afterLazy = this.tryFindRoute(request);
1512
+ if (afterLazy) return afterLazy;
1513
+ throw new NotFoundException(`No route matches ${request.method} ${request.path}`);
1514
+ }
1515
+ /**
1516
+ * Given a request path, checks whether a lazy route prefix matches
1517
+ * and triggers the dynamic import if it hasn't been loaded yet.
1518
+ */
1519
+ async tryLoadLazyRoute(requestPath) {
1520
+ const firstSegment = requestPath.replace(/^\/+/, "").split("/")[0] ?? "";
1521
+ for (const [prefix, entry] of this.lazyRoutes) {
1522
+ if (entry.loaded) continue;
1523
+ const normalizedPath = requestPath.replace(/^\/+/, "");
1524
+ if (normalizedPath === prefix || normalizedPath.startsWith(prefix + "/") || firstSegment === prefix) {
1525
+ if (!entry.loading) {
1526
+ entry.loading = this.loadLazyModule(prefix, entry);
1527
+ }
1528
+ await entry.loading;
1529
+ return;
1530
+ }
1441
1531
  }
1442
- return routeDef.value;
1532
+ }
1533
+ /**
1534
+ * Dynamically imports a lazy module and registers its decorated classes
1535
+ * (controllers, services) in the DI container using the two-phase strategy.
1536
+ */
1537
+ async loadLazyModule(prefix, entry) {
1538
+ const t0 = performance.now();
1539
+ InjectorExplorer.beginAccumulate();
1540
+ await entry.loadModule();
1541
+ InjectorExplorer.flushAccumulated();
1542
+ entry.loaded = true;
1543
+ const t1 = performance.now();
1544
+ Logger.info(`Lazy-loaded module for prefix {${prefix}} in ${Math.round(t1 - t0)}ms`);
1443
1545
  }
1444
1546
  /**
1445
1547
  * Resolves the controller for a given route definition.
@@ -1752,8 +1854,42 @@ var _NoxApp = class _NoxApp {
1752
1854
  * This window will be passed to IApp.onReady when start() is called.
1753
1855
  * @param window - The BrowserWindow created during bootstrap.
1754
1856
  */
1755
- setMainWindow(window2) {
1756
- this.mainWindow = window2;
1857
+ setMainWindow(window) {
1858
+ this.mainWindow = window;
1859
+ }
1860
+ /**
1861
+ * Registers a lazy-loaded route. The module behind this path prefix
1862
+ * will only be dynamically imported when the first IPC request
1863
+ * targets this prefix — like Angular's loadChildren.
1864
+ *
1865
+ * @example
1866
+ * ```ts
1867
+ * noxApp.lazy("auth", () => import("./modules/auth/auth.module.js"));
1868
+ * noxApp.lazy("printing", () => import("./modules/printing/printing.module.js"));
1869
+ * ```
1870
+ *
1871
+ * @param pathPrefix - The route prefix (e.g. "auth", "cash-register").
1872
+ * @param loadModule - A function returning a dynamic import promise.
1873
+ * @returns NoxApp instance for method chaining.
1874
+ */
1875
+ lazy(pathPrefix, loadModule) {
1876
+ this.router.registerLazyRoute(pathPrefix, loadModule);
1877
+ return this;
1878
+ }
1879
+ /**
1880
+ * Eagerly loads one or more modules with a two-phase DI guarantee.
1881
+ * Use this when a service needed at startup lives inside a module
1882
+ * (e.g. the Application service depends on LoaderService).
1883
+ *
1884
+ * All dynamic imports run in parallel; bindings are registered first,
1885
+ * then singletons are resolved — safe regardless of import ordering.
1886
+ *
1887
+ * @param importFns - Functions returning dynamic import promises.
1888
+ */
1889
+ async loadModules(importFns) {
1890
+ InjectorExplorer.beginAccumulate();
1891
+ await Promise.all(importFns.map((fn) => fn()));
1892
+ InjectorExplorer.flushAccumulated();
1757
1893
  }
1758
1894
  /**
1759
1895
  * Configures the NoxApp instance with the provided application class.
@@ -1799,13 +1935,21 @@ NoxApp = _ts_decorate3([
1799
1935
  // src/bootstrap.ts
1800
1936
  var import_main2 = require("electron/main");
1801
1937
  async function bootstrapApplication(rootModule, options) {
1802
- if (!getModuleMetadata(rootModule)) {
1938
+ if (rootModule && !getModuleMetadata(rootModule)) {
1803
1939
  throw new Error(`Root module must be decorated with @Module`);
1804
1940
  }
1805
1941
  await import_main2.app.whenReady();
1806
1942
  let mainWindow;
1807
1943
  if (options?.window) {
1808
1944
  mainWindow = new import_main2.BrowserWindow(options.window);
1945
+ mainWindow.once("ready-to-show", () => {
1946
+ mainWindow?.show();
1947
+ });
1948
+ const primaryDisplay = import_main2.screen.getPrimaryDisplay();
1949
+ const { width, height } = primaryDisplay.workAreaSize;
1950
+ if (options.window.minWidth && options.window.minHeight) {
1951
+ mainWindow.setSize(Math.min(width, options.window.minWidth), Math.min(height, options.window.minHeight), true);
1952
+ }
1809
1953
  }
1810
1954
  InjectorExplorer.processPending();
1811
1955
  const noxApp = inject(NoxApp);
@@ -1816,368 +1960,6 @@ async function bootstrapApplication(rootModule, options) {
1816
1960
  return noxApp;
1817
1961
  }
1818
1962
  __name(bootstrapApplication, "bootstrapApplication");
1819
-
1820
- // src/preload-bridge.ts
1821
- var import_renderer = require("electron/renderer");
1822
- var DEFAULT_EXPOSE_NAME = "noxus";
1823
- var DEFAULT_INIT_EVENT = "init-port";
1824
- var DEFAULT_REQUEST_CHANNEL = "gimme-my-port";
1825
- var DEFAULT_RESPONSE_CHANNEL = "port";
1826
- function exposeNoxusBridge(options = {}) {
1827
- const { exposeAs = DEFAULT_EXPOSE_NAME, initMessageType = DEFAULT_INIT_EVENT, requestChannel = DEFAULT_REQUEST_CHANNEL, responseChannel = DEFAULT_RESPONSE_CHANNEL, targetWindow = window } = options;
1828
- const api = {
1829
- requestPort: /* @__PURE__ */ __name(() => {
1830
- import_renderer.ipcRenderer.send(requestChannel);
1831
- import_renderer.ipcRenderer.once(responseChannel, (event, message) => {
1832
- const ports = (event.ports ?? []).filter((port) => port !== void 0);
1833
- if (ports.length === 0) {
1834
- console.error("[Noxus] No MessagePort received from main process.");
1835
- return;
1836
- }
1837
- for (const port of ports) {
1838
- try {
1839
- port.start();
1840
- } catch (error) {
1841
- console.error("[Noxus] Failed to start MessagePort.", error);
1842
- }
1843
- }
1844
- targetWindow.postMessage({
1845
- type: initMessageType,
1846
- senderId: message?.senderId
1847
- }, "*", ports);
1848
- });
1849
- }, "requestPort")
1850
- };
1851
- import_renderer.contextBridge.exposeInMainWorld(exposeAs, api);
1852
- return api;
1853
- }
1854
- __name(exposeNoxusBridge, "exposeNoxusBridge");
1855
-
1856
- // src/renderer-events.ts
1857
- var _RendererEventRegistry = class _RendererEventRegistry {
1858
- constructor() {
1859
- __publicField(this, "listeners", /* @__PURE__ */ new Map());
1860
- }
1861
- /**
1862
- *
1863
- */
1864
- subscribe(eventName, handler) {
1865
- const normalizedEventName = eventName.trim();
1866
- if (normalizedEventName.length === 0) {
1867
- throw new Error("Renderer event name must be a non-empty string.");
1868
- }
1869
- const handlers = this.listeners.get(normalizedEventName) ?? /* @__PURE__ */ new Set();
1870
- handlers.add(handler);
1871
- this.listeners.set(normalizedEventName, handlers);
1872
- return {
1873
- unsubscribe: /* @__PURE__ */ __name(() => this.unsubscribe(normalizedEventName, handler), "unsubscribe")
1874
- };
1875
- }
1876
- /**
1877
- *
1878
- */
1879
- unsubscribe(eventName, handler) {
1880
- const handlers = this.listeners.get(eventName);
1881
- if (!handlers) {
1882
- return;
1883
- }
1884
- handlers.delete(handler);
1885
- if (handlers.size === 0) {
1886
- this.listeners.delete(eventName);
1887
- }
1888
- }
1889
- /**
1890
- *
1891
- */
1892
- clear(eventName) {
1893
- if (eventName) {
1894
- this.listeners.delete(eventName);
1895
- return;
1896
- }
1897
- this.listeners.clear();
1898
- }
1899
- /**
1900
- *
1901
- */
1902
- dispatch(message) {
1903
- const handlers = this.listeners.get(message.event);
1904
- if (!handlers || handlers.size === 0) {
1905
- return;
1906
- }
1907
- handlers.forEach((handler) => {
1908
- try {
1909
- handler(message.payload);
1910
- } catch (error) {
1911
- console.error(`[Noxus] Renderer event handler for "${message.event}" threw an error.`, error);
1912
- }
1913
- });
1914
- }
1915
- /**
1916
- *
1917
- */
1918
- tryDispatchFromMessageEvent(event) {
1919
- if (!isRendererEventMessage(event.data)) {
1920
- return false;
1921
- }
1922
- this.dispatch(event.data);
1923
- return true;
1924
- }
1925
- /**
1926
- *
1927
- */
1928
- hasHandlers(eventName) {
1929
- const handlers = this.listeners.get(eventName);
1930
- return !!handlers && handlers.size > 0;
1931
- }
1932
- };
1933
- __name(_RendererEventRegistry, "RendererEventRegistry");
1934
- var RendererEventRegistry = _RendererEventRegistry;
1935
-
1936
- // src/renderer-client.ts
1937
- var DEFAULT_INIT_EVENT2 = "init-port";
1938
- var DEFAULT_BRIDGE_NAMES = [
1939
- "noxus",
1940
- "ipcRenderer"
1941
- ];
1942
- function defaultRequestId() {
1943
- if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
1944
- return crypto.randomUUID();
1945
- }
1946
- return `${Date.now().toString(16)}-${Math.floor(Math.random() * 1e8).toString(16)}`;
1947
- }
1948
- __name(defaultRequestId, "defaultRequestId");
1949
- function normalizeBridgeNames(preferred) {
1950
- const names = [];
1951
- const add = /* @__PURE__ */ __name((name) => {
1952
- if (!name) return;
1953
- if (!names.includes(name)) {
1954
- names.push(name);
1955
- }
1956
- }, "add");
1957
- if (Array.isArray(preferred)) {
1958
- for (const name of preferred) {
1959
- add(name);
1960
- }
1961
- } else {
1962
- add(preferred);
1963
- }
1964
- for (const fallback of DEFAULT_BRIDGE_NAMES) {
1965
- add(fallback);
1966
- }
1967
- return names;
1968
- }
1969
- __name(normalizeBridgeNames, "normalizeBridgeNames");
1970
- function resolveBridgeFromWindow(windowRef, preferred) {
1971
- const names = normalizeBridgeNames(preferred);
1972
- const globalRef = windowRef;
1973
- if (!globalRef) {
1974
- return null;
1975
- }
1976
- for (const name of names) {
1977
- const candidate = globalRef[name];
1978
- if (candidate && typeof candidate.requestPort === "function") {
1979
- return candidate;
1980
- }
1981
- }
1982
- return null;
1983
- }
1984
- __name(resolveBridgeFromWindow, "resolveBridgeFromWindow");
1985
- var _NoxRendererClient = class _NoxRendererClient {
1986
- constructor(options = {}) {
1987
- __publicField(this, "events", new RendererEventRegistry());
1988
- __publicField(this, "pendingRequests", /* @__PURE__ */ new Map());
1989
- __publicField(this, "requestPort");
1990
- __publicField(this, "socketPort");
1991
- __publicField(this, "senderId");
1992
- __publicField(this, "bridge");
1993
- __publicField(this, "initMessageType");
1994
- __publicField(this, "windowRef");
1995
- __publicField(this, "generateRequestId");
1996
- __publicField(this, "isReady", false);
1997
- __publicField(this, "setupPromise");
1998
- __publicField(this, "setupResolve");
1999
- __publicField(this, "setupReject");
2000
- __publicField(this, "onWindowMessage", /* @__PURE__ */ __name((event) => {
2001
- if (event.data?.type !== this.initMessageType) {
2002
- return;
2003
- }
2004
- if (!Array.isArray(event.ports) || event.ports.length < 2) {
2005
- const error = new Error("[Noxus] Renderer expected two MessagePorts (request + socket).");
2006
- console.error(error);
2007
- this.setupReject?.(error);
2008
- this.resetSetupState();
2009
- return;
2010
- }
2011
- this.windowRef.removeEventListener("message", this.onWindowMessage);
2012
- this.requestPort = event.ports[0];
2013
- this.socketPort = event.ports[1];
2014
- this.senderId = event.data.senderId;
2015
- if (this.requestPort === void 0 || this.socketPort === void 0) {
2016
- const error = new Error("[Noxus] Renderer failed to receive valid MessagePorts.");
2017
- console.error(error);
2018
- this.setupReject?.(error);
2019
- this.resetSetupState();
2020
- return;
2021
- }
2022
- this.attachRequestPort(this.requestPort);
2023
- this.attachSocketPort(this.socketPort);
2024
- this.isReady = true;
2025
- this.setupResolve?.();
2026
- this.resetSetupState(true);
2027
- }, "onWindowMessage"));
2028
- __publicField(this, "onSocketMessage", /* @__PURE__ */ __name((event) => {
2029
- if (this.events.tryDispatchFromMessageEvent(event)) {
2030
- return;
2031
- }
2032
- console.warn("[Noxus] Received a socket message that is not a renderer event payload.", event.data);
2033
- }, "onSocketMessage"));
2034
- __publicField(this, "onRequestMessage", /* @__PURE__ */ __name((event) => {
2035
- if (this.events.tryDispatchFromMessageEvent(event)) {
2036
- return;
2037
- }
2038
- const response = event.data;
2039
- if (!response || typeof response.requestId !== "string") {
2040
- console.error("[Noxus] Renderer received an invalid response payload.", response);
2041
- return;
2042
- }
2043
- const pending = this.pendingRequests.get(response.requestId);
2044
- if (!pending) {
2045
- console.error(`[Noxus] No pending handler found for request ${response.requestId}.`);
2046
- return;
2047
- }
2048
- this.pendingRequests.delete(response.requestId);
2049
- this.onRequestCompleted(pending, response);
2050
- if (response.status >= 400) {
2051
- pending.reject(response);
2052
- return;
2053
- }
2054
- pending.resolve(response.body);
2055
- }, "onRequestMessage"));
2056
- this.windowRef = options.windowRef ?? window;
2057
- const resolvedBridge = options.bridge ?? resolveBridgeFromWindow(this.windowRef, options.bridgeName);
2058
- this.bridge = resolvedBridge ?? null;
2059
- this.initMessageType = options.initMessageType ?? DEFAULT_INIT_EVENT2;
2060
- this.generateRequestId = options.generateRequestId ?? defaultRequestId;
2061
- }
2062
- async setup() {
2063
- if (this.isReady) {
2064
- return Promise.resolve();
2065
- }
2066
- if (this.setupPromise) {
2067
- return this.setupPromise;
2068
- }
2069
- if (!this.bridge || typeof this.bridge.requestPort !== "function") {
2070
- throw new Error("[Noxus] Renderer bridge is missing requestPort().");
2071
- }
2072
- this.setupPromise = new Promise((resolve, reject) => {
2073
- this.setupResolve = resolve;
2074
- this.setupReject = reject;
2075
- });
2076
- this.windowRef.addEventListener("message", this.onWindowMessage);
2077
- this.bridge.requestPort();
2078
- return this.setupPromise;
2079
- }
2080
- dispose() {
2081
- this.windowRef.removeEventListener("message", this.onWindowMessage);
2082
- this.requestPort?.close();
2083
- this.socketPort?.close();
2084
- this.requestPort = void 0;
2085
- this.socketPort = void 0;
2086
- this.senderId = void 0;
2087
- this.isReady = false;
2088
- this.pendingRequests.clear();
2089
- }
2090
- async request(request) {
2091
- const senderId = this.senderId;
2092
- const requestId = this.generateRequestId();
2093
- if (senderId === void 0) {
2094
- return Promise.reject(this.createErrorResponse(requestId, "MessagePort is not available"));
2095
- }
2096
- const readinessError = this.validateReady(requestId);
2097
- if (readinessError) {
2098
- return Promise.reject(readinessError);
2099
- }
2100
- const message = {
2101
- requestId,
2102
- senderId,
2103
- ...request
2104
- };
2105
- return new Promise((resolve, reject) => {
2106
- const pending = {
2107
- resolve,
2108
- reject: /* @__PURE__ */ __name((response) => reject(response), "reject"),
2109
- request: message,
2110
- submittedAt: Date.now()
2111
- };
2112
- this.pendingRequests.set(message.requestId, pending);
2113
- this.requestPort.postMessage(message);
2114
- });
2115
- }
2116
- async batch(requests) {
2117
- return this.request({
2118
- method: "BATCH",
2119
- path: "",
2120
- body: {
2121
- requests
2122
- }
2123
- });
2124
- }
2125
- getSenderId() {
2126
- return this.senderId;
2127
- }
2128
- onRequestCompleted(pending, response) {
2129
- if (typeof console.groupCollapsed === "function") {
2130
- console.groupCollapsed(`${response.status} ${pending.request.method} /${pending.request.path}`);
2131
- }
2132
- if (response.error) {
2133
- console.error("error message:", response.error);
2134
- }
2135
- if (response.body !== void 0) {
2136
- console.info("response:", response.body);
2137
- }
2138
- console.info("request:", pending.request);
2139
- console.info(`Request duration: ${Date.now() - pending.submittedAt} ms`);
2140
- if (typeof console.groupCollapsed === "function") {
2141
- console.groupEnd();
2142
- }
2143
- }
2144
- attachRequestPort(port) {
2145
- port.onmessage = this.onRequestMessage;
2146
- port.start();
2147
- }
2148
- attachSocketPort(port) {
2149
- port.onmessage = this.onSocketMessage;
2150
- port.start();
2151
- }
2152
- validateReady(requestId) {
2153
- if (!this.isElectronEnvironment()) {
2154
- return this.createErrorResponse(requestId, "Not running in Electron environment");
2155
- }
2156
- if (!this.requestPort) {
2157
- return this.createErrorResponse(requestId, "MessagePort is not available");
2158
- }
2159
- return void 0;
2160
- }
2161
- createErrorResponse(requestId, message) {
2162
- return {
2163
- status: 500,
2164
- requestId,
2165
- error: message
2166
- };
2167
- }
2168
- resetSetupState(success = false) {
2169
- if (!success) {
2170
- this.setupPromise = void 0;
2171
- }
2172
- this.setupResolve = void 0;
2173
- this.setupReject = void 0;
2174
- }
2175
- isElectronEnvironment() {
2176
- return typeof window !== "undefined" && /Electron/.test(window.navigator.userAgent);
2177
- }
2178
- };
2179
- __name(_NoxRendererClient, "NoxRendererClient");
2180
- var NoxRendererClient = _NoxRendererClient;
2181
1963
  // Annotate the CommonJS export names for ESM import in node:
2182
1964
  0 && (module.exports = {
2183
1965
  AppInjector,
@@ -2211,7 +1993,6 @@ var NoxRendererClient = _NoxRendererClient;
2211
1993
  NotFoundException,
2212
1994
  NotImplementedException,
2213
1995
  NoxApp,
2214
- NoxRendererClient,
2215
1996
  NoxSocket,
2216
1997
  Patch,
2217
1998
  PaymentRequiredException,
@@ -2219,7 +2000,6 @@ var NoxRendererClient = _NoxRendererClient;
2219
2000
  Put,
2220
2001
  RENDERER_EVENT_TYPE,
2221
2002
  ROUTE_METADATA_KEY,
2222
- RendererEventRegistry,
2223
2003
  Request,
2224
2004
  RequestTimeoutException,
2225
2005
  ResponseException,
@@ -2233,7 +2013,6 @@ var NoxRendererClient = _NoxRendererClient;
2233
2013
  VariantAlsoNegotiatesException,
2234
2014
  bootstrapApplication,
2235
2015
  createRendererEventMessage,
2236
- exposeNoxusBridge,
2237
2016
  forwardRef,
2238
2017
  getControllerMetadata,
2239
2018
  getGuardForController,