@noxfly/noxus 2.3.2 → 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/child.js +173 -19
- package/dist/child.mjs +173 -19
- package/dist/main.d.mts +100 -22
- package/dist/main.d.ts +100 -22
- package/dist/main.js +236 -390
- package/dist/main.mjs +237 -388
- package/dist/renderer.d.mts +112 -1
- package/dist/renderer.d.ts +112 -1
- package/dist/renderer.js +40 -2
- package/dist/renderer.mjs +39 -2
- package/dist/{index-BxWQVi6C.d.ts → request-CdpZ9qZL.d.ts} +1 -87
- package/dist/{index-DQBQQfMw.d.mts → request-Dx_5Prte.d.mts} +1 -87
- package/package.json +1 -1
- package/src/DI/injector-explorer.ts +120 -15
- package/src/app.ts +50 -2
- package/src/bootstrap.ts +53 -3
- package/src/decorators/injectable.decorator.ts +1 -1
- package/src/index.ts +1 -0
- package/src/main.ts +0 -3
- package/src/router.ts +99 -6
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,
|
|
@@ -825,41 +822,130 @@ var Logger;
|
|
|
825
822
|
// src/DI/injector-explorer.ts
|
|
826
823
|
var _InjectorExplorer = class _InjectorExplorer {
|
|
827
824
|
/**
|
|
828
|
-
*
|
|
829
|
-
*
|
|
830
|
-
*
|
|
825
|
+
* Enqueues a class for deferred registration.
|
|
826
|
+
* Called by the @Injectable decorator at import time.
|
|
827
|
+
*
|
|
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.
|
|
836
|
+
*/
|
|
837
|
+
static enqueue(target, lifetime) {
|
|
838
|
+
if (_InjectorExplorer.processed && !_InjectorExplorer.accumulating) {
|
|
839
|
+
_InjectorExplorer.registerImmediate(target, lifetime);
|
|
840
|
+
return;
|
|
841
|
+
}
|
|
842
|
+
_InjectorExplorer.pending.push({
|
|
843
|
+
target,
|
|
844
|
+
lifetime
|
|
845
|
+
});
|
|
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.
|
|
831
862
|
*/
|
|
832
|
-
static
|
|
833
|
-
|
|
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
|
+
}
|
|
881
|
+
/**
|
|
882
|
+
* Processes all pending registrations in two phases:
|
|
883
|
+
* 1. Register all bindings (no instantiation) so every dependency is known.
|
|
884
|
+
* 2. Resolve singletons, register controllers and log module readiness.
|
|
885
|
+
*
|
|
886
|
+
* This two-phase approach makes the system resilient to import ordering:
|
|
887
|
+
* all bindings exist before any singleton is instantiated.
|
|
888
|
+
*/
|
|
889
|
+
static processPending() {
|
|
890
|
+
const queue = _InjectorExplorer.pending;
|
|
891
|
+
for (const { target, lifetime } of queue) {
|
|
892
|
+
if (!RootInjector.bindings.has(target)) {
|
|
893
|
+
RootInjector.bindings.set(target, {
|
|
894
|
+
implementation: target,
|
|
895
|
+
lifetime
|
|
896
|
+
});
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
for (const { target, lifetime } of queue) {
|
|
900
|
+
_InjectorExplorer.processRegistration(target, lifetime);
|
|
901
|
+
}
|
|
902
|
+
queue.length = 0;
|
|
903
|
+
_InjectorExplorer.processed = true;
|
|
904
|
+
}
|
|
905
|
+
/**
|
|
906
|
+
* Registers a single class immediately (post-bootstrap path).
|
|
907
|
+
* Used for classes discovered via late dynamic imports.
|
|
908
|
+
*/
|
|
909
|
+
static registerImmediate(target, lifetime) {
|
|
910
|
+
if (RootInjector.bindings.has(target)) {
|
|
911
|
+
return;
|
|
912
|
+
}
|
|
834
913
|
RootInjector.bindings.set(target, {
|
|
835
914
|
implementation: target,
|
|
836
915
|
lifetime
|
|
837
916
|
});
|
|
917
|
+
_InjectorExplorer.processRegistration(target, lifetime);
|
|
918
|
+
}
|
|
919
|
+
/**
|
|
920
|
+
* Performs phase-2 work for a single registration: resolve singletons,
|
|
921
|
+
* register controllers, and log module readiness.
|
|
922
|
+
*/
|
|
923
|
+
static processRegistration(target, lifetime) {
|
|
838
924
|
if (lifetime === "singleton") {
|
|
839
925
|
RootInjector.resolve(target);
|
|
840
926
|
}
|
|
841
927
|
if (getModuleMetadata(target)) {
|
|
842
928
|
Logger.log(`${target.name} dependencies initialized`);
|
|
843
|
-
return
|
|
929
|
+
return;
|
|
844
930
|
}
|
|
845
931
|
const controllerMeta = getControllerMetadata(target);
|
|
846
932
|
if (controllerMeta) {
|
|
847
933
|
const router = RootInjector.resolve(Router);
|
|
848
934
|
router?.registerController(target);
|
|
849
|
-
return
|
|
935
|
+
return;
|
|
850
936
|
}
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
return RootInjector;
|
|
937
|
+
if (getRouteMetadata(target).length > 0) {
|
|
938
|
+
return;
|
|
854
939
|
}
|
|
855
940
|
if (getInjectableMetadata(target)) {
|
|
856
941
|
Logger.log(`Registered ${target.name} as ${lifetime}`);
|
|
857
|
-
return RootInjector;
|
|
858
942
|
}
|
|
859
|
-
return RootInjector;
|
|
860
943
|
}
|
|
861
944
|
};
|
|
862
945
|
__name(_InjectorExplorer, "InjectorExplorer");
|
|
946
|
+
__publicField(_InjectorExplorer, "pending", []);
|
|
947
|
+
__publicField(_InjectorExplorer, "processed", false);
|
|
948
|
+
__publicField(_InjectorExplorer, "accumulating", false);
|
|
863
949
|
var InjectorExplorer = _InjectorExplorer;
|
|
864
950
|
|
|
865
951
|
// src/decorators/injectable.decorator.ts
|
|
@@ -869,7 +955,7 @@ function Injectable(lifetime = "scope") {
|
|
|
869
955
|
throw new Error(`@Injectable can only be used on classes, not on ${typeof target}`);
|
|
870
956
|
}
|
|
871
957
|
defineInjectableMetadata(target, lifetime);
|
|
872
|
-
InjectorExplorer.
|
|
958
|
+
InjectorExplorer.enqueue(target, lifetime);
|
|
873
959
|
};
|
|
874
960
|
}
|
|
875
961
|
__name(Injectable, "Injectable");
|
|
@@ -1144,6 +1230,7 @@ var _Router = class _Router {
|
|
|
1144
1230
|
constructor() {
|
|
1145
1231
|
__publicField(this, "routes", new RadixTree());
|
|
1146
1232
|
__publicField(this, "rootMiddlewares", []);
|
|
1233
|
+
__publicField(this, "lazyRoutes", /* @__PURE__ */ new Map());
|
|
1147
1234
|
}
|
|
1148
1235
|
/**
|
|
1149
1236
|
* Registers a controller class with the router.
|
|
@@ -1191,6 +1278,24 @@ var _Router = class _Router {
|
|
|
1191
1278
|
Logger.log(`Mapped ${controllerClass.name}${controllerGuardsInfo} controller's routes`);
|
|
1192
1279
|
return this;
|
|
1193
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
|
+
}
|
|
1194
1299
|
/**
|
|
1195
1300
|
* Defines a middleware for the root of the application.
|
|
1196
1301
|
* This method allows you to register a middleware that will be applied to all requests
|
|
@@ -1223,7 +1328,7 @@ var _Router = class _Router {
|
|
|
1223
1328
|
};
|
|
1224
1329
|
let isCritical = false;
|
|
1225
1330
|
try {
|
|
1226
|
-
const routeDef = this.findRoute(request);
|
|
1331
|
+
const routeDef = await this.findRoute(request);
|
|
1227
1332
|
await this.resolveController(request, response, routeDef);
|
|
1228
1333
|
if (response.status > 400) {
|
|
1229
1334
|
throw new ResponseException(response.status, response.error);
|
|
@@ -1381,16 +1486,62 @@ var _Router = class _Router {
|
|
|
1381
1486
|
* @param request - The Request object containing the method and path to search for.
|
|
1382
1487
|
* @returns The IRouteDefinition for the matched route.
|
|
1383
1488
|
*/
|
|
1384
|
-
|
|
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) {
|
|
1385
1495
|
const matchedRoutes = this.routes.search(request.path);
|
|
1386
1496
|
if (matchedRoutes?.node === void 0 || matchedRoutes.node.children.length === 0) {
|
|
1387
|
-
|
|
1497
|
+
return void 0;
|
|
1388
1498
|
}
|
|
1389
1499
|
const routeDef = matchedRoutes.node.findExactChild(request.method);
|
|
1390
|
-
|
|
1391
|
-
|
|
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
|
+
}
|
|
1392
1531
|
}
|
|
1393
|
-
|
|
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`);
|
|
1394
1545
|
}
|
|
1395
1546
|
/**
|
|
1396
1547
|
* Resolves the controller for a given route definition.
|
|
@@ -1591,6 +1742,7 @@ var _NoxApp = class _NoxApp {
|
|
|
1591
1742
|
__publicField(this, "router");
|
|
1592
1743
|
__publicField(this, "socket");
|
|
1593
1744
|
__publicField(this, "app");
|
|
1745
|
+
__publicField(this, "mainWindow");
|
|
1594
1746
|
/**
|
|
1595
1747
|
*
|
|
1596
1748
|
*/
|
|
@@ -1697,6 +1849,48 @@ var _NoxApp = class _NoxApp {
|
|
|
1697
1849
|
}
|
|
1698
1850
|
}
|
|
1699
1851
|
// ---
|
|
1852
|
+
/**
|
|
1853
|
+
* Sets the main BrowserWindow that was created early by bootstrapApplication.
|
|
1854
|
+
* This window will be passed to IApp.onReady when start() is called.
|
|
1855
|
+
* @param window - The BrowserWindow created during bootstrap.
|
|
1856
|
+
*/
|
|
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();
|
|
1893
|
+
}
|
|
1700
1894
|
/**
|
|
1701
1895
|
* Configures the NoxApp instance with the provided application class.
|
|
1702
1896
|
* This method allows you to set the application class that will handle lifecycle events.
|
|
@@ -1719,10 +1913,11 @@ var _NoxApp = class _NoxApp {
|
|
|
1719
1913
|
}
|
|
1720
1914
|
/**
|
|
1721
1915
|
* Should be called after the bootstrapApplication function is called.
|
|
1916
|
+
* Passes the early-created BrowserWindow (if any) to the configured IApp service.
|
|
1722
1917
|
* @returns NoxApp instance for method chaining.
|
|
1723
1918
|
*/
|
|
1724
1919
|
start() {
|
|
1725
|
-
this.app?.onReady();
|
|
1920
|
+
this.app?.onReady(this.mainWindow);
|
|
1726
1921
|
return this;
|
|
1727
1922
|
}
|
|
1728
1923
|
};
|
|
@@ -1739,378 +1934,32 @@ NoxApp = _ts_decorate3([
|
|
|
1739
1934
|
|
|
1740
1935
|
// src/bootstrap.ts
|
|
1741
1936
|
var import_main2 = require("electron/main");
|
|
1742
|
-
async function bootstrapApplication(rootModule) {
|
|
1743
|
-
if (!getModuleMetadata(rootModule)) {
|
|
1937
|
+
async function bootstrapApplication(rootModule, options) {
|
|
1938
|
+
if (rootModule && !getModuleMetadata(rootModule)) {
|
|
1744
1939
|
throw new Error(`Root module must be decorated with @Module`);
|
|
1745
1940
|
}
|
|
1746
1941
|
await import_main2.app.whenReady();
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
// src/preload-bridge.ts
|
|
1754
|
-
var import_renderer = require("electron/renderer");
|
|
1755
|
-
var DEFAULT_EXPOSE_NAME = "noxus";
|
|
1756
|
-
var DEFAULT_INIT_EVENT = "init-port";
|
|
1757
|
-
var DEFAULT_REQUEST_CHANNEL = "gimme-my-port";
|
|
1758
|
-
var DEFAULT_RESPONSE_CHANNEL = "port";
|
|
1759
|
-
function exposeNoxusBridge(options = {}) {
|
|
1760
|
-
const { exposeAs = DEFAULT_EXPOSE_NAME, initMessageType = DEFAULT_INIT_EVENT, requestChannel = DEFAULT_REQUEST_CHANNEL, responseChannel = DEFAULT_RESPONSE_CHANNEL, targetWindow = window } = options;
|
|
1761
|
-
const api = {
|
|
1762
|
-
requestPort: /* @__PURE__ */ __name(() => {
|
|
1763
|
-
import_renderer.ipcRenderer.send(requestChannel);
|
|
1764
|
-
import_renderer.ipcRenderer.once(responseChannel, (event, message) => {
|
|
1765
|
-
const ports = (event.ports ?? []).filter((port) => port !== void 0);
|
|
1766
|
-
if (ports.length === 0) {
|
|
1767
|
-
console.error("[Noxus] No MessagePort received from main process.");
|
|
1768
|
-
return;
|
|
1769
|
-
}
|
|
1770
|
-
for (const port of ports) {
|
|
1771
|
-
try {
|
|
1772
|
-
port.start();
|
|
1773
|
-
} catch (error) {
|
|
1774
|
-
console.error("[Noxus] Failed to start MessagePort.", error);
|
|
1775
|
-
}
|
|
1776
|
-
}
|
|
1777
|
-
targetWindow.postMessage({
|
|
1778
|
-
type: initMessageType,
|
|
1779
|
-
senderId: message?.senderId
|
|
1780
|
-
}, "*", ports);
|
|
1781
|
-
});
|
|
1782
|
-
}, "requestPort")
|
|
1783
|
-
};
|
|
1784
|
-
import_renderer.contextBridge.exposeInMainWorld(exposeAs, api);
|
|
1785
|
-
return api;
|
|
1786
|
-
}
|
|
1787
|
-
__name(exposeNoxusBridge, "exposeNoxusBridge");
|
|
1788
|
-
|
|
1789
|
-
// src/renderer-events.ts
|
|
1790
|
-
var _RendererEventRegistry = class _RendererEventRegistry {
|
|
1791
|
-
constructor() {
|
|
1792
|
-
__publicField(this, "listeners", /* @__PURE__ */ new Map());
|
|
1793
|
-
}
|
|
1794
|
-
/**
|
|
1795
|
-
*
|
|
1796
|
-
*/
|
|
1797
|
-
subscribe(eventName, handler) {
|
|
1798
|
-
const normalizedEventName = eventName.trim();
|
|
1799
|
-
if (normalizedEventName.length === 0) {
|
|
1800
|
-
throw new Error("Renderer event name must be a non-empty string.");
|
|
1801
|
-
}
|
|
1802
|
-
const handlers = this.listeners.get(normalizedEventName) ?? /* @__PURE__ */ new Set();
|
|
1803
|
-
handlers.add(handler);
|
|
1804
|
-
this.listeners.set(normalizedEventName, handlers);
|
|
1805
|
-
return {
|
|
1806
|
-
unsubscribe: /* @__PURE__ */ __name(() => this.unsubscribe(normalizedEventName, handler), "unsubscribe")
|
|
1807
|
-
};
|
|
1808
|
-
}
|
|
1809
|
-
/**
|
|
1810
|
-
*
|
|
1811
|
-
*/
|
|
1812
|
-
unsubscribe(eventName, handler) {
|
|
1813
|
-
const handlers = this.listeners.get(eventName);
|
|
1814
|
-
if (!handlers) {
|
|
1815
|
-
return;
|
|
1816
|
-
}
|
|
1817
|
-
handlers.delete(handler);
|
|
1818
|
-
if (handlers.size === 0) {
|
|
1819
|
-
this.listeners.delete(eventName);
|
|
1820
|
-
}
|
|
1821
|
-
}
|
|
1822
|
-
/**
|
|
1823
|
-
*
|
|
1824
|
-
*/
|
|
1825
|
-
clear(eventName) {
|
|
1826
|
-
if (eventName) {
|
|
1827
|
-
this.listeners.delete(eventName);
|
|
1828
|
-
return;
|
|
1829
|
-
}
|
|
1830
|
-
this.listeners.clear();
|
|
1831
|
-
}
|
|
1832
|
-
/**
|
|
1833
|
-
*
|
|
1834
|
-
*/
|
|
1835
|
-
dispatch(message) {
|
|
1836
|
-
const handlers = this.listeners.get(message.event);
|
|
1837
|
-
if (!handlers || handlers.size === 0) {
|
|
1838
|
-
return;
|
|
1839
|
-
}
|
|
1840
|
-
handlers.forEach((handler) => {
|
|
1841
|
-
try {
|
|
1842
|
-
handler(message.payload);
|
|
1843
|
-
} catch (error) {
|
|
1844
|
-
console.error(`[Noxus] Renderer event handler for "${message.event}" threw an error.`, error);
|
|
1845
|
-
}
|
|
1942
|
+
let mainWindow;
|
|
1943
|
+
if (options?.window) {
|
|
1944
|
+
mainWindow = new import_main2.BrowserWindow(options.window);
|
|
1945
|
+
mainWindow.once("ready-to-show", () => {
|
|
1946
|
+
mainWindow?.show();
|
|
1846
1947
|
});
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
tryDispatchFromMessageEvent(event) {
|
|
1852
|
-
if (!isRendererEventMessage(event.data)) {
|
|
1853
|
-
return false;
|
|
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);
|
|
1854
1952
|
}
|
|
1855
|
-
this.dispatch(event.data);
|
|
1856
|
-
return true;
|
|
1857
1953
|
}
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
const handlers = this.listeners.get(eventName);
|
|
1863
|
-
return !!handlers && handlers.size > 0;
|
|
1864
|
-
}
|
|
1865
|
-
};
|
|
1866
|
-
__name(_RendererEventRegistry, "RendererEventRegistry");
|
|
1867
|
-
var RendererEventRegistry = _RendererEventRegistry;
|
|
1868
|
-
|
|
1869
|
-
// src/renderer-client.ts
|
|
1870
|
-
var DEFAULT_INIT_EVENT2 = "init-port";
|
|
1871
|
-
var DEFAULT_BRIDGE_NAMES = [
|
|
1872
|
-
"noxus",
|
|
1873
|
-
"ipcRenderer"
|
|
1874
|
-
];
|
|
1875
|
-
function defaultRequestId() {
|
|
1876
|
-
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
|
|
1877
|
-
return crypto.randomUUID();
|
|
1878
|
-
}
|
|
1879
|
-
return `${Date.now().toString(16)}-${Math.floor(Math.random() * 1e8).toString(16)}`;
|
|
1880
|
-
}
|
|
1881
|
-
__name(defaultRequestId, "defaultRequestId");
|
|
1882
|
-
function normalizeBridgeNames(preferred) {
|
|
1883
|
-
const names = [];
|
|
1884
|
-
const add = /* @__PURE__ */ __name((name) => {
|
|
1885
|
-
if (!name) return;
|
|
1886
|
-
if (!names.includes(name)) {
|
|
1887
|
-
names.push(name);
|
|
1888
|
-
}
|
|
1889
|
-
}, "add");
|
|
1890
|
-
if (Array.isArray(preferred)) {
|
|
1891
|
-
for (const name of preferred) {
|
|
1892
|
-
add(name);
|
|
1893
|
-
}
|
|
1894
|
-
} else {
|
|
1895
|
-
add(preferred);
|
|
1896
|
-
}
|
|
1897
|
-
for (const fallback of DEFAULT_BRIDGE_NAMES) {
|
|
1898
|
-
add(fallback);
|
|
1899
|
-
}
|
|
1900
|
-
return names;
|
|
1901
|
-
}
|
|
1902
|
-
__name(normalizeBridgeNames, "normalizeBridgeNames");
|
|
1903
|
-
function resolveBridgeFromWindow(windowRef, preferred) {
|
|
1904
|
-
const names = normalizeBridgeNames(preferred);
|
|
1905
|
-
const globalRef = windowRef;
|
|
1906
|
-
if (!globalRef) {
|
|
1907
|
-
return null;
|
|
1908
|
-
}
|
|
1909
|
-
for (const name of names) {
|
|
1910
|
-
const candidate = globalRef[name];
|
|
1911
|
-
if (candidate && typeof candidate.requestPort === "function") {
|
|
1912
|
-
return candidate;
|
|
1913
|
-
}
|
|
1954
|
+
InjectorExplorer.processPending();
|
|
1955
|
+
const noxApp = inject(NoxApp);
|
|
1956
|
+
if (mainWindow) {
|
|
1957
|
+
noxApp.setMainWindow(mainWindow);
|
|
1914
1958
|
}
|
|
1915
|
-
|
|
1959
|
+
await noxApp.init();
|
|
1960
|
+
return noxApp;
|
|
1916
1961
|
}
|
|
1917
|
-
__name(
|
|
1918
|
-
var _NoxRendererClient = class _NoxRendererClient {
|
|
1919
|
-
constructor(options = {}) {
|
|
1920
|
-
__publicField(this, "events", new RendererEventRegistry());
|
|
1921
|
-
__publicField(this, "pendingRequests", /* @__PURE__ */ new Map());
|
|
1922
|
-
__publicField(this, "requestPort");
|
|
1923
|
-
__publicField(this, "socketPort");
|
|
1924
|
-
__publicField(this, "senderId");
|
|
1925
|
-
__publicField(this, "bridge");
|
|
1926
|
-
__publicField(this, "initMessageType");
|
|
1927
|
-
__publicField(this, "windowRef");
|
|
1928
|
-
__publicField(this, "generateRequestId");
|
|
1929
|
-
__publicField(this, "isReady", false);
|
|
1930
|
-
__publicField(this, "setupPromise");
|
|
1931
|
-
__publicField(this, "setupResolve");
|
|
1932
|
-
__publicField(this, "setupReject");
|
|
1933
|
-
__publicField(this, "onWindowMessage", /* @__PURE__ */ __name((event) => {
|
|
1934
|
-
if (event.data?.type !== this.initMessageType) {
|
|
1935
|
-
return;
|
|
1936
|
-
}
|
|
1937
|
-
if (!Array.isArray(event.ports) || event.ports.length < 2) {
|
|
1938
|
-
const error = new Error("[Noxus] Renderer expected two MessagePorts (request + socket).");
|
|
1939
|
-
console.error(error);
|
|
1940
|
-
this.setupReject?.(error);
|
|
1941
|
-
this.resetSetupState();
|
|
1942
|
-
return;
|
|
1943
|
-
}
|
|
1944
|
-
this.windowRef.removeEventListener("message", this.onWindowMessage);
|
|
1945
|
-
this.requestPort = event.ports[0];
|
|
1946
|
-
this.socketPort = event.ports[1];
|
|
1947
|
-
this.senderId = event.data.senderId;
|
|
1948
|
-
if (this.requestPort === void 0 || this.socketPort === void 0) {
|
|
1949
|
-
const error = new Error("[Noxus] Renderer failed to receive valid MessagePorts.");
|
|
1950
|
-
console.error(error);
|
|
1951
|
-
this.setupReject?.(error);
|
|
1952
|
-
this.resetSetupState();
|
|
1953
|
-
return;
|
|
1954
|
-
}
|
|
1955
|
-
this.attachRequestPort(this.requestPort);
|
|
1956
|
-
this.attachSocketPort(this.socketPort);
|
|
1957
|
-
this.isReady = true;
|
|
1958
|
-
this.setupResolve?.();
|
|
1959
|
-
this.resetSetupState(true);
|
|
1960
|
-
}, "onWindowMessage"));
|
|
1961
|
-
__publicField(this, "onSocketMessage", /* @__PURE__ */ __name((event) => {
|
|
1962
|
-
if (this.events.tryDispatchFromMessageEvent(event)) {
|
|
1963
|
-
return;
|
|
1964
|
-
}
|
|
1965
|
-
console.warn("[Noxus] Received a socket message that is not a renderer event payload.", event.data);
|
|
1966
|
-
}, "onSocketMessage"));
|
|
1967
|
-
__publicField(this, "onRequestMessage", /* @__PURE__ */ __name((event) => {
|
|
1968
|
-
if (this.events.tryDispatchFromMessageEvent(event)) {
|
|
1969
|
-
return;
|
|
1970
|
-
}
|
|
1971
|
-
const response = event.data;
|
|
1972
|
-
if (!response || typeof response.requestId !== "string") {
|
|
1973
|
-
console.error("[Noxus] Renderer received an invalid response payload.", response);
|
|
1974
|
-
return;
|
|
1975
|
-
}
|
|
1976
|
-
const pending = this.pendingRequests.get(response.requestId);
|
|
1977
|
-
if (!pending) {
|
|
1978
|
-
console.error(`[Noxus] No pending handler found for request ${response.requestId}.`);
|
|
1979
|
-
return;
|
|
1980
|
-
}
|
|
1981
|
-
this.pendingRequests.delete(response.requestId);
|
|
1982
|
-
this.onRequestCompleted(pending, response);
|
|
1983
|
-
if (response.status >= 400) {
|
|
1984
|
-
pending.reject(response);
|
|
1985
|
-
return;
|
|
1986
|
-
}
|
|
1987
|
-
pending.resolve(response.body);
|
|
1988
|
-
}, "onRequestMessage"));
|
|
1989
|
-
this.windowRef = options.windowRef ?? window;
|
|
1990
|
-
const resolvedBridge = options.bridge ?? resolveBridgeFromWindow(this.windowRef, options.bridgeName);
|
|
1991
|
-
this.bridge = resolvedBridge ?? null;
|
|
1992
|
-
this.initMessageType = options.initMessageType ?? DEFAULT_INIT_EVENT2;
|
|
1993
|
-
this.generateRequestId = options.generateRequestId ?? defaultRequestId;
|
|
1994
|
-
}
|
|
1995
|
-
async setup() {
|
|
1996
|
-
if (this.isReady) {
|
|
1997
|
-
return Promise.resolve();
|
|
1998
|
-
}
|
|
1999
|
-
if (this.setupPromise) {
|
|
2000
|
-
return this.setupPromise;
|
|
2001
|
-
}
|
|
2002
|
-
if (!this.bridge || typeof this.bridge.requestPort !== "function") {
|
|
2003
|
-
throw new Error("[Noxus] Renderer bridge is missing requestPort().");
|
|
2004
|
-
}
|
|
2005
|
-
this.setupPromise = new Promise((resolve, reject) => {
|
|
2006
|
-
this.setupResolve = resolve;
|
|
2007
|
-
this.setupReject = reject;
|
|
2008
|
-
});
|
|
2009
|
-
this.windowRef.addEventListener("message", this.onWindowMessage);
|
|
2010
|
-
this.bridge.requestPort();
|
|
2011
|
-
return this.setupPromise;
|
|
2012
|
-
}
|
|
2013
|
-
dispose() {
|
|
2014
|
-
this.windowRef.removeEventListener("message", this.onWindowMessage);
|
|
2015
|
-
this.requestPort?.close();
|
|
2016
|
-
this.socketPort?.close();
|
|
2017
|
-
this.requestPort = void 0;
|
|
2018
|
-
this.socketPort = void 0;
|
|
2019
|
-
this.senderId = void 0;
|
|
2020
|
-
this.isReady = false;
|
|
2021
|
-
this.pendingRequests.clear();
|
|
2022
|
-
}
|
|
2023
|
-
async request(request) {
|
|
2024
|
-
const senderId = this.senderId;
|
|
2025
|
-
const requestId = this.generateRequestId();
|
|
2026
|
-
if (senderId === void 0) {
|
|
2027
|
-
return Promise.reject(this.createErrorResponse(requestId, "MessagePort is not available"));
|
|
2028
|
-
}
|
|
2029
|
-
const readinessError = this.validateReady(requestId);
|
|
2030
|
-
if (readinessError) {
|
|
2031
|
-
return Promise.reject(readinessError);
|
|
2032
|
-
}
|
|
2033
|
-
const message = {
|
|
2034
|
-
requestId,
|
|
2035
|
-
senderId,
|
|
2036
|
-
...request
|
|
2037
|
-
};
|
|
2038
|
-
return new Promise((resolve, reject) => {
|
|
2039
|
-
const pending = {
|
|
2040
|
-
resolve,
|
|
2041
|
-
reject: /* @__PURE__ */ __name((response) => reject(response), "reject"),
|
|
2042
|
-
request: message,
|
|
2043
|
-
submittedAt: Date.now()
|
|
2044
|
-
};
|
|
2045
|
-
this.pendingRequests.set(message.requestId, pending);
|
|
2046
|
-
this.requestPort.postMessage(message);
|
|
2047
|
-
});
|
|
2048
|
-
}
|
|
2049
|
-
async batch(requests) {
|
|
2050
|
-
return this.request({
|
|
2051
|
-
method: "BATCH",
|
|
2052
|
-
path: "",
|
|
2053
|
-
body: {
|
|
2054
|
-
requests
|
|
2055
|
-
}
|
|
2056
|
-
});
|
|
2057
|
-
}
|
|
2058
|
-
getSenderId() {
|
|
2059
|
-
return this.senderId;
|
|
2060
|
-
}
|
|
2061
|
-
onRequestCompleted(pending, response) {
|
|
2062
|
-
if (typeof console.groupCollapsed === "function") {
|
|
2063
|
-
console.groupCollapsed(`${response.status} ${pending.request.method} /${pending.request.path}`);
|
|
2064
|
-
}
|
|
2065
|
-
if (response.error) {
|
|
2066
|
-
console.error("error message:", response.error);
|
|
2067
|
-
}
|
|
2068
|
-
if (response.body !== void 0) {
|
|
2069
|
-
console.info("response:", response.body);
|
|
2070
|
-
}
|
|
2071
|
-
console.info("request:", pending.request);
|
|
2072
|
-
console.info(`Request duration: ${Date.now() - pending.submittedAt} ms`);
|
|
2073
|
-
if (typeof console.groupCollapsed === "function") {
|
|
2074
|
-
console.groupEnd();
|
|
2075
|
-
}
|
|
2076
|
-
}
|
|
2077
|
-
attachRequestPort(port) {
|
|
2078
|
-
port.onmessage = this.onRequestMessage;
|
|
2079
|
-
port.start();
|
|
2080
|
-
}
|
|
2081
|
-
attachSocketPort(port) {
|
|
2082
|
-
port.onmessage = this.onSocketMessage;
|
|
2083
|
-
port.start();
|
|
2084
|
-
}
|
|
2085
|
-
validateReady(requestId) {
|
|
2086
|
-
if (!this.isElectronEnvironment()) {
|
|
2087
|
-
return this.createErrorResponse(requestId, "Not running in Electron environment");
|
|
2088
|
-
}
|
|
2089
|
-
if (!this.requestPort) {
|
|
2090
|
-
return this.createErrorResponse(requestId, "MessagePort is not available");
|
|
2091
|
-
}
|
|
2092
|
-
return void 0;
|
|
2093
|
-
}
|
|
2094
|
-
createErrorResponse(requestId, message) {
|
|
2095
|
-
return {
|
|
2096
|
-
status: 500,
|
|
2097
|
-
requestId,
|
|
2098
|
-
error: message
|
|
2099
|
-
};
|
|
2100
|
-
}
|
|
2101
|
-
resetSetupState(success = false) {
|
|
2102
|
-
if (!success) {
|
|
2103
|
-
this.setupPromise = void 0;
|
|
2104
|
-
}
|
|
2105
|
-
this.setupResolve = void 0;
|
|
2106
|
-
this.setupReject = void 0;
|
|
2107
|
-
}
|
|
2108
|
-
isElectronEnvironment() {
|
|
2109
|
-
return typeof window !== "undefined" && /Electron/.test(window.navigator.userAgent);
|
|
2110
|
-
}
|
|
2111
|
-
};
|
|
2112
|
-
__name(_NoxRendererClient, "NoxRendererClient");
|
|
2113
|
-
var NoxRendererClient = _NoxRendererClient;
|
|
1962
|
+
__name(bootstrapApplication, "bootstrapApplication");
|
|
2114
1963
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2115
1964
|
0 && (module.exports = {
|
|
2116
1965
|
AppInjector,
|
|
@@ -2144,7 +1993,6 @@ var NoxRendererClient = _NoxRendererClient;
|
|
|
2144
1993
|
NotFoundException,
|
|
2145
1994
|
NotImplementedException,
|
|
2146
1995
|
NoxApp,
|
|
2147
|
-
NoxRendererClient,
|
|
2148
1996
|
NoxSocket,
|
|
2149
1997
|
Patch,
|
|
2150
1998
|
PaymentRequiredException,
|
|
@@ -2152,7 +2000,6 @@ var NoxRendererClient = _NoxRendererClient;
|
|
|
2152
2000
|
Put,
|
|
2153
2001
|
RENDERER_EVENT_TYPE,
|
|
2154
2002
|
ROUTE_METADATA_KEY,
|
|
2155
|
-
RendererEventRegistry,
|
|
2156
2003
|
Request,
|
|
2157
2004
|
RequestTimeoutException,
|
|
2158
2005
|
ResponseException,
|
|
@@ -2166,7 +2013,6 @@ var NoxRendererClient = _NoxRendererClient;
|
|
|
2166
2013
|
VariantAlsoNegotiatesException,
|
|
2167
2014
|
bootstrapApplication,
|
|
2168
2015
|
createRendererEventMessage,
|
|
2169
|
-
exposeNoxusBridge,
|
|
2170
2016
|
forwardRef,
|
|
2171
2017
|
getControllerMetadata,
|
|
2172
2018
|
getGuardForController,
|