@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/child.js +115 -10
- package/dist/child.mjs +115 -10
- package/dist/main.d.mts +72 -21
- package/dist/main.d.ts +72 -21
- package/dist/main.js +160 -381
- package/dist/main.mjs +161 -379
- 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 +49 -4
- package/src/app.ts +37 -0
- package/src/bootstrap.ts +18 -3
- package/src/index.ts +1 -0
- package/src/main.ts +0 -3
- package/src/router.ts +99 -6
package/dist/main.mjs
CHANGED
|
@@ -729,12 +729,17 @@ var _InjectorExplorer = class _InjectorExplorer {
|
|
|
729
729
|
* Enqueues a class for deferred registration.
|
|
730
730
|
* Called by the @Injectable decorator at import time.
|
|
731
731
|
*
|
|
732
|
-
* If {@link processPending} has already been called (i.e. after bootstrap)
|
|
733
|
-
*
|
|
734
|
-
* (e.g. middlewares loaded after bootstrap)
|
|
732
|
+
* If {@link processPending} has already been called (i.e. after bootstrap)
|
|
733
|
+
* and accumulation mode is not active, the class is registered immediately
|
|
734
|
+
* so that late dynamic imports (e.g. middlewares loaded after bootstrap)
|
|
735
|
+
* work correctly.
|
|
736
|
+
*
|
|
737
|
+
* When accumulation mode is active (between {@link beginAccumulate} and
|
|
738
|
+
* {@link flushAccumulated}), classes are queued instead — preserving the
|
|
739
|
+
* two-phase binding/resolution guarantee for lazy-loaded modules.
|
|
735
740
|
*/
|
|
736
741
|
static enqueue(target, lifetime) {
|
|
737
|
-
if (_InjectorExplorer.processed) {
|
|
742
|
+
if (_InjectorExplorer.processed && !_InjectorExplorer.accumulating) {
|
|
738
743
|
_InjectorExplorer.registerImmediate(target, lifetime);
|
|
739
744
|
return;
|
|
740
745
|
}
|
|
@@ -743,6 +748,40 @@ var _InjectorExplorer = class _InjectorExplorer {
|
|
|
743
748
|
lifetime
|
|
744
749
|
});
|
|
745
750
|
}
|
|
751
|
+
/**
|
|
752
|
+
* Enters accumulation mode. While active, all decorated classes discovered
|
|
753
|
+
* via dynamic imports are queued in {@link pending} rather than registered
|
|
754
|
+
* immediately. Call {@link flushAccumulated} to process them with the
|
|
755
|
+
* full two-phase (bind-then-resolve) guarantee.
|
|
756
|
+
*/
|
|
757
|
+
static beginAccumulate() {
|
|
758
|
+
_InjectorExplorer.accumulating = true;
|
|
759
|
+
}
|
|
760
|
+
/**
|
|
761
|
+
* Exits accumulation mode and processes every class queued since
|
|
762
|
+
* {@link beginAccumulate} was called. Uses the same two-phase strategy
|
|
763
|
+
* as {@link processPending} (register all bindings first, then resolve
|
|
764
|
+
* singletons / controllers) so import ordering within a lazy batch
|
|
765
|
+
* does not cause resolution failures.
|
|
766
|
+
*/
|
|
767
|
+
static flushAccumulated() {
|
|
768
|
+
_InjectorExplorer.accumulating = false;
|
|
769
|
+
const queue = [
|
|
770
|
+
..._InjectorExplorer.pending
|
|
771
|
+
];
|
|
772
|
+
_InjectorExplorer.pending.length = 0;
|
|
773
|
+
for (const { target, lifetime } of queue) {
|
|
774
|
+
if (!RootInjector.bindings.has(target)) {
|
|
775
|
+
RootInjector.bindings.set(target, {
|
|
776
|
+
implementation: target,
|
|
777
|
+
lifetime
|
|
778
|
+
});
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
for (const { target, lifetime } of queue) {
|
|
782
|
+
_InjectorExplorer.processRegistration(target, lifetime);
|
|
783
|
+
}
|
|
784
|
+
}
|
|
746
785
|
/**
|
|
747
786
|
* Processes all pending registrations in two phases:
|
|
748
787
|
* 1. Register all bindings (no instantiation) so every dependency is known.
|
|
@@ -810,6 +849,7 @@ var _InjectorExplorer = class _InjectorExplorer {
|
|
|
810
849
|
__name(_InjectorExplorer, "InjectorExplorer");
|
|
811
850
|
__publicField(_InjectorExplorer, "pending", []);
|
|
812
851
|
__publicField(_InjectorExplorer, "processed", false);
|
|
852
|
+
__publicField(_InjectorExplorer, "accumulating", false);
|
|
813
853
|
var InjectorExplorer = _InjectorExplorer;
|
|
814
854
|
|
|
815
855
|
// src/decorators/injectable.decorator.ts
|
|
@@ -1094,6 +1134,7 @@ var _Router = class _Router {
|
|
|
1094
1134
|
constructor() {
|
|
1095
1135
|
__publicField(this, "routes", new RadixTree());
|
|
1096
1136
|
__publicField(this, "rootMiddlewares", []);
|
|
1137
|
+
__publicField(this, "lazyRoutes", /* @__PURE__ */ new Map());
|
|
1097
1138
|
}
|
|
1098
1139
|
/**
|
|
1099
1140
|
* Registers a controller class with the router.
|
|
@@ -1141,6 +1182,24 @@ var _Router = class _Router {
|
|
|
1141
1182
|
Logger.log(`Mapped ${controllerClass.name}${controllerGuardsInfo} controller's routes`);
|
|
1142
1183
|
return this;
|
|
1143
1184
|
}
|
|
1185
|
+
/**
|
|
1186
|
+
* Registers a lazy route. The module behind this route prefix will only
|
|
1187
|
+
* be imported (and its controllers/services registered in DI) the first
|
|
1188
|
+
* time a request targets this prefix.
|
|
1189
|
+
*
|
|
1190
|
+
* @param pathPrefix - Route prefix (e.g. "auth"). Matched against the first segment of the request path.
|
|
1191
|
+
* @param loadModule - A function that returns a dynamic import promise.
|
|
1192
|
+
*/
|
|
1193
|
+
registerLazyRoute(pathPrefix, loadModule) {
|
|
1194
|
+
const normalized = pathPrefix.replace(/^\/+|\/+$/g, "");
|
|
1195
|
+
this.lazyRoutes.set(normalized, {
|
|
1196
|
+
loadModule,
|
|
1197
|
+
loading: null,
|
|
1198
|
+
loaded: false
|
|
1199
|
+
});
|
|
1200
|
+
Logger.log(`Registered lazy route prefix {${normalized}}`);
|
|
1201
|
+
return this;
|
|
1202
|
+
}
|
|
1144
1203
|
/**
|
|
1145
1204
|
* Defines a middleware for the root of the application.
|
|
1146
1205
|
* This method allows you to register a middleware that will be applied to all requests
|
|
@@ -1173,7 +1232,7 @@ var _Router = class _Router {
|
|
|
1173
1232
|
};
|
|
1174
1233
|
let isCritical = false;
|
|
1175
1234
|
try {
|
|
1176
|
-
const routeDef = this.findRoute(request);
|
|
1235
|
+
const routeDef = await this.findRoute(request);
|
|
1177
1236
|
await this.resolveController(request, response, routeDef);
|
|
1178
1237
|
if (response.status > 400) {
|
|
1179
1238
|
throw new ResponseException(response.status, response.error);
|
|
@@ -1331,16 +1390,62 @@ var _Router = class _Router {
|
|
|
1331
1390
|
* @param request - The Request object containing the method and path to search for.
|
|
1332
1391
|
* @returns The IRouteDefinition for the matched route.
|
|
1333
1392
|
*/
|
|
1334
|
-
|
|
1393
|
+
/**
|
|
1394
|
+
* Attempts to find a route definition for the given request.
|
|
1395
|
+
* Returns undefined instead of throwing when the route is not found,
|
|
1396
|
+
* so the caller can try lazy-loading first.
|
|
1397
|
+
*/
|
|
1398
|
+
tryFindRoute(request) {
|
|
1335
1399
|
const matchedRoutes = this.routes.search(request.path);
|
|
1336
1400
|
if (matchedRoutes?.node === void 0 || matchedRoutes.node.children.length === 0) {
|
|
1337
|
-
|
|
1401
|
+
return void 0;
|
|
1338
1402
|
}
|
|
1339
1403
|
const routeDef = matchedRoutes.node.findExactChild(request.method);
|
|
1340
|
-
|
|
1341
|
-
|
|
1404
|
+
return routeDef?.value;
|
|
1405
|
+
}
|
|
1406
|
+
/**
|
|
1407
|
+
* Finds the route definition for a given request.
|
|
1408
|
+
* If no eagerly-registered route matches, attempts to load a lazy module
|
|
1409
|
+
* whose prefix matches the request path, then retries.
|
|
1410
|
+
*/
|
|
1411
|
+
async findRoute(request) {
|
|
1412
|
+
const direct = this.tryFindRoute(request);
|
|
1413
|
+
if (direct) return direct;
|
|
1414
|
+
await this.tryLoadLazyRoute(request.path);
|
|
1415
|
+
const afterLazy = this.tryFindRoute(request);
|
|
1416
|
+
if (afterLazy) return afterLazy;
|
|
1417
|
+
throw new NotFoundException(`No route matches ${request.method} ${request.path}`);
|
|
1418
|
+
}
|
|
1419
|
+
/**
|
|
1420
|
+
* Given a request path, checks whether a lazy route prefix matches
|
|
1421
|
+
* and triggers the dynamic import if it hasn't been loaded yet.
|
|
1422
|
+
*/
|
|
1423
|
+
async tryLoadLazyRoute(requestPath) {
|
|
1424
|
+
const firstSegment = requestPath.replace(/^\/+/, "").split("/")[0] ?? "";
|
|
1425
|
+
for (const [prefix, entry] of this.lazyRoutes) {
|
|
1426
|
+
if (entry.loaded) continue;
|
|
1427
|
+
const normalizedPath = requestPath.replace(/^\/+/, "");
|
|
1428
|
+
if (normalizedPath === prefix || normalizedPath.startsWith(prefix + "/") || firstSegment === prefix) {
|
|
1429
|
+
if (!entry.loading) {
|
|
1430
|
+
entry.loading = this.loadLazyModule(prefix, entry);
|
|
1431
|
+
}
|
|
1432
|
+
await entry.loading;
|
|
1433
|
+
return;
|
|
1434
|
+
}
|
|
1342
1435
|
}
|
|
1343
|
-
|
|
1436
|
+
}
|
|
1437
|
+
/**
|
|
1438
|
+
* Dynamically imports a lazy module and registers its decorated classes
|
|
1439
|
+
* (controllers, services) in the DI container using the two-phase strategy.
|
|
1440
|
+
*/
|
|
1441
|
+
async loadLazyModule(prefix, entry) {
|
|
1442
|
+
const t0 = performance.now();
|
|
1443
|
+
InjectorExplorer.beginAccumulate();
|
|
1444
|
+
await entry.loadModule();
|
|
1445
|
+
InjectorExplorer.flushAccumulated();
|
|
1446
|
+
entry.loaded = true;
|
|
1447
|
+
const t1 = performance.now();
|
|
1448
|
+
Logger.info(`Lazy-loaded module for prefix {${prefix}} in ${Math.round(t1 - t0)}ms`);
|
|
1344
1449
|
}
|
|
1345
1450
|
/**
|
|
1346
1451
|
* Resolves the controller for a given route definition.
|
|
@@ -1653,8 +1758,42 @@ var _NoxApp = class _NoxApp {
|
|
|
1653
1758
|
* This window will be passed to IApp.onReady when start() is called.
|
|
1654
1759
|
* @param window - The BrowserWindow created during bootstrap.
|
|
1655
1760
|
*/
|
|
1656
|
-
setMainWindow(
|
|
1657
|
-
this.mainWindow =
|
|
1761
|
+
setMainWindow(window) {
|
|
1762
|
+
this.mainWindow = window;
|
|
1763
|
+
}
|
|
1764
|
+
/**
|
|
1765
|
+
* Registers a lazy-loaded route. The module behind this path prefix
|
|
1766
|
+
* will only be dynamically imported when the first IPC request
|
|
1767
|
+
* targets this prefix — like Angular's loadChildren.
|
|
1768
|
+
*
|
|
1769
|
+
* @example
|
|
1770
|
+
* ```ts
|
|
1771
|
+
* noxApp.lazy("auth", () => import("./modules/auth/auth.module.js"));
|
|
1772
|
+
* noxApp.lazy("printing", () => import("./modules/printing/printing.module.js"));
|
|
1773
|
+
* ```
|
|
1774
|
+
*
|
|
1775
|
+
* @param pathPrefix - The route prefix (e.g. "auth", "cash-register").
|
|
1776
|
+
* @param loadModule - A function returning a dynamic import promise.
|
|
1777
|
+
* @returns NoxApp instance for method chaining.
|
|
1778
|
+
*/
|
|
1779
|
+
lazy(pathPrefix, loadModule) {
|
|
1780
|
+
this.router.registerLazyRoute(pathPrefix, loadModule);
|
|
1781
|
+
return this;
|
|
1782
|
+
}
|
|
1783
|
+
/**
|
|
1784
|
+
* Eagerly loads one or more modules with a two-phase DI guarantee.
|
|
1785
|
+
* Use this when a service needed at startup lives inside a module
|
|
1786
|
+
* (e.g. the Application service depends on LoaderService).
|
|
1787
|
+
*
|
|
1788
|
+
* All dynamic imports run in parallel; bindings are registered first,
|
|
1789
|
+
* then singletons are resolved — safe regardless of import ordering.
|
|
1790
|
+
*
|
|
1791
|
+
* @param importFns - Functions returning dynamic import promises.
|
|
1792
|
+
*/
|
|
1793
|
+
async loadModules(importFns) {
|
|
1794
|
+
InjectorExplorer.beginAccumulate();
|
|
1795
|
+
await Promise.all(importFns.map((fn) => fn()));
|
|
1796
|
+
InjectorExplorer.flushAccumulated();
|
|
1658
1797
|
}
|
|
1659
1798
|
/**
|
|
1660
1799
|
* Configures the NoxApp instance with the provided application class.
|
|
@@ -1698,15 +1837,23 @@ NoxApp = _ts_decorate3([
|
|
|
1698
1837
|
], NoxApp);
|
|
1699
1838
|
|
|
1700
1839
|
// src/bootstrap.ts
|
|
1701
|
-
import { app as app2, BrowserWindow as BrowserWindow2 } from "electron/main";
|
|
1840
|
+
import { app as app2, BrowserWindow as BrowserWindow2, screen } from "electron/main";
|
|
1702
1841
|
async function bootstrapApplication(rootModule, options) {
|
|
1703
|
-
if (!getModuleMetadata(rootModule)) {
|
|
1842
|
+
if (rootModule && !getModuleMetadata(rootModule)) {
|
|
1704
1843
|
throw new Error(`Root module must be decorated with @Module`);
|
|
1705
1844
|
}
|
|
1706
1845
|
await app2.whenReady();
|
|
1707
1846
|
let mainWindow;
|
|
1708
1847
|
if (options?.window) {
|
|
1709
1848
|
mainWindow = new BrowserWindow2(options.window);
|
|
1849
|
+
mainWindow.once("ready-to-show", () => {
|
|
1850
|
+
mainWindow?.show();
|
|
1851
|
+
});
|
|
1852
|
+
const primaryDisplay = screen.getPrimaryDisplay();
|
|
1853
|
+
const { width, height } = primaryDisplay.workAreaSize;
|
|
1854
|
+
if (options.window.minWidth && options.window.minHeight) {
|
|
1855
|
+
mainWindow.setSize(Math.min(width, options.window.minWidth), Math.min(height, options.window.minHeight), true);
|
|
1856
|
+
}
|
|
1710
1857
|
}
|
|
1711
1858
|
InjectorExplorer.processPending();
|
|
1712
1859
|
const noxApp = inject(NoxApp);
|
|
@@ -1717,368 +1864,6 @@ async function bootstrapApplication(rootModule, options) {
|
|
|
1717
1864
|
return noxApp;
|
|
1718
1865
|
}
|
|
1719
1866
|
__name(bootstrapApplication, "bootstrapApplication");
|
|
1720
|
-
|
|
1721
|
-
// src/preload-bridge.ts
|
|
1722
|
-
import { contextBridge, ipcRenderer } from "electron/renderer";
|
|
1723
|
-
var DEFAULT_EXPOSE_NAME = "noxus";
|
|
1724
|
-
var DEFAULT_INIT_EVENT = "init-port";
|
|
1725
|
-
var DEFAULT_REQUEST_CHANNEL = "gimme-my-port";
|
|
1726
|
-
var DEFAULT_RESPONSE_CHANNEL = "port";
|
|
1727
|
-
function exposeNoxusBridge(options = {}) {
|
|
1728
|
-
const { exposeAs = DEFAULT_EXPOSE_NAME, initMessageType = DEFAULT_INIT_EVENT, requestChannel = DEFAULT_REQUEST_CHANNEL, responseChannel = DEFAULT_RESPONSE_CHANNEL, targetWindow = window } = options;
|
|
1729
|
-
const api = {
|
|
1730
|
-
requestPort: /* @__PURE__ */ __name(() => {
|
|
1731
|
-
ipcRenderer.send(requestChannel);
|
|
1732
|
-
ipcRenderer.once(responseChannel, (event, message) => {
|
|
1733
|
-
const ports = (event.ports ?? []).filter((port) => port !== void 0);
|
|
1734
|
-
if (ports.length === 0) {
|
|
1735
|
-
console.error("[Noxus] No MessagePort received from main process.");
|
|
1736
|
-
return;
|
|
1737
|
-
}
|
|
1738
|
-
for (const port of ports) {
|
|
1739
|
-
try {
|
|
1740
|
-
port.start();
|
|
1741
|
-
} catch (error) {
|
|
1742
|
-
console.error("[Noxus] Failed to start MessagePort.", error);
|
|
1743
|
-
}
|
|
1744
|
-
}
|
|
1745
|
-
targetWindow.postMessage({
|
|
1746
|
-
type: initMessageType,
|
|
1747
|
-
senderId: message?.senderId
|
|
1748
|
-
}, "*", ports);
|
|
1749
|
-
});
|
|
1750
|
-
}, "requestPort")
|
|
1751
|
-
};
|
|
1752
|
-
contextBridge.exposeInMainWorld(exposeAs, api);
|
|
1753
|
-
return api;
|
|
1754
|
-
}
|
|
1755
|
-
__name(exposeNoxusBridge, "exposeNoxusBridge");
|
|
1756
|
-
|
|
1757
|
-
// src/renderer-events.ts
|
|
1758
|
-
var _RendererEventRegistry = class _RendererEventRegistry {
|
|
1759
|
-
constructor() {
|
|
1760
|
-
__publicField(this, "listeners", /* @__PURE__ */ new Map());
|
|
1761
|
-
}
|
|
1762
|
-
/**
|
|
1763
|
-
*
|
|
1764
|
-
*/
|
|
1765
|
-
subscribe(eventName, handler) {
|
|
1766
|
-
const normalizedEventName = eventName.trim();
|
|
1767
|
-
if (normalizedEventName.length === 0) {
|
|
1768
|
-
throw new Error("Renderer event name must be a non-empty string.");
|
|
1769
|
-
}
|
|
1770
|
-
const handlers = this.listeners.get(normalizedEventName) ?? /* @__PURE__ */ new Set();
|
|
1771
|
-
handlers.add(handler);
|
|
1772
|
-
this.listeners.set(normalizedEventName, handlers);
|
|
1773
|
-
return {
|
|
1774
|
-
unsubscribe: /* @__PURE__ */ __name(() => this.unsubscribe(normalizedEventName, handler), "unsubscribe")
|
|
1775
|
-
};
|
|
1776
|
-
}
|
|
1777
|
-
/**
|
|
1778
|
-
*
|
|
1779
|
-
*/
|
|
1780
|
-
unsubscribe(eventName, handler) {
|
|
1781
|
-
const handlers = this.listeners.get(eventName);
|
|
1782
|
-
if (!handlers) {
|
|
1783
|
-
return;
|
|
1784
|
-
}
|
|
1785
|
-
handlers.delete(handler);
|
|
1786
|
-
if (handlers.size === 0) {
|
|
1787
|
-
this.listeners.delete(eventName);
|
|
1788
|
-
}
|
|
1789
|
-
}
|
|
1790
|
-
/**
|
|
1791
|
-
*
|
|
1792
|
-
*/
|
|
1793
|
-
clear(eventName) {
|
|
1794
|
-
if (eventName) {
|
|
1795
|
-
this.listeners.delete(eventName);
|
|
1796
|
-
return;
|
|
1797
|
-
}
|
|
1798
|
-
this.listeners.clear();
|
|
1799
|
-
}
|
|
1800
|
-
/**
|
|
1801
|
-
*
|
|
1802
|
-
*/
|
|
1803
|
-
dispatch(message) {
|
|
1804
|
-
const handlers = this.listeners.get(message.event);
|
|
1805
|
-
if (!handlers || handlers.size === 0) {
|
|
1806
|
-
return;
|
|
1807
|
-
}
|
|
1808
|
-
handlers.forEach((handler) => {
|
|
1809
|
-
try {
|
|
1810
|
-
handler(message.payload);
|
|
1811
|
-
} catch (error) {
|
|
1812
|
-
console.error(`[Noxus] Renderer event handler for "${message.event}" threw an error.`, error);
|
|
1813
|
-
}
|
|
1814
|
-
});
|
|
1815
|
-
}
|
|
1816
|
-
/**
|
|
1817
|
-
*
|
|
1818
|
-
*/
|
|
1819
|
-
tryDispatchFromMessageEvent(event) {
|
|
1820
|
-
if (!isRendererEventMessage(event.data)) {
|
|
1821
|
-
return false;
|
|
1822
|
-
}
|
|
1823
|
-
this.dispatch(event.data);
|
|
1824
|
-
return true;
|
|
1825
|
-
}
|
|
1826
|
-
/**
|
|
1827
|
-
*
|
|
1828
|
-
*/
|
|
1829
|
-
hasHandlers(eventName) {
|
|
1830
|
-
const handlers = this.listeners.get(eventName);
|
|
1831
|
-
return !!handlers && handlers.size > 0;
|
|
1832
|
-
}
|
|
1833
|
-
};
|
|
1834
|
-
__name(_RendererEventRegistry, "RendererEventRegistry");
|
|
1835
|
-
var RendererEventRegistry = _RendererEventRegistry;
|
|
1836
|
-
|
|
1837
|
-
// src/renderer-client.ts
|
|
1838
|
-
var DEFAULT_INIT_EVENT2 = "init-port";
|
|
1839
|
-
var DEFAULT_BRIDGE_NAMES = [
|
|
1840
|
-
"noxus",
|
|
1841
|
-
"ipcRenderer"
|
|
1842
|
-
];
|
|
1843
|
-
function defaultRequestId() {
|
|
1844
|
-
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
|
|
1845
|
-
return crypto.randomUUID();
|
|
1846
|
-
}
|
|
1847
|
-
return `${Date.now().toString(16)}-${Math.floor(Math.random() * 1e8).toString(16)}`;
|
|
1848
|
-
}
|
|
1849
|
-
__name(defaultRequestId, "defaultRequestId");
|
|
1850
|
-
function normalizeBridgeNames(preferred) {
|
|
1851
|
-
const names = [];
|
|
1852
|
-
const add = /* @__PURE__ */ __name((name) => {
|
|
1853
|
-
if (!name) return;
|
|
1854
|
-
if (!names.includes(name)) {
|
|
1855
|
-
names.push(name);
|
|
1856
|
-
}
|
|
1857
|
-
}, "add");
|
|
1858
|
-
if (Array.isArray(preferred)) {
|
|
1859
|
-
for (const name of preferred) {
|
|
1860
|
-
add(name);
|
|
1861
|
-
}
|
|
1862
|
-
} else {
|
|
1863
|
-
add(preferred);
|
|
1864
|
-
}
|
|
1865
|
-
for (const fallback of DEFAULT_BRIDGE_NAMES) {
|
|
1866
|
-
add(fallback);
|
|
1867
|
-
}
|
|
1868
|
-
return names;
|
|
1869
|
-
}
|
|
1870
|
-
__name(normalizeBridgeNames, "normalizeBridgeNames");
|
|
1871
|
-
function resolveBridgeFromWindow(windowRef, preferred) {
|
|
1872
|
-
const names = normalizeBridgeNames(preferred);
|
|
1873
|
-
const globalRef = windowRef;
|
|
1874
|
-
if (!globalRef) {
|
|
1875
|
-
return null;
|
|
1876
|
-
}
|
|
1877
|
-
for (const name of names) {
|
|
1878
|
-
const candidate = globalRef[name];
|
|
1879
|
-
if (candidate && typeof candidate.requestPort === "function") {
|
|
1880
|
-
return candidate;
|
|
1881
|
-
}
|
|
1882
|
-
}
|
|
1883
|
-
return null;
|
|
1884
|
-
}
|
|
1885
|
-
__name(resolveBridgeFromWindow, "resolveBridgeFromWindow");
|
|
1886
|
-
var _NoxRendererClient = class _NoxRendererClient {
|
|
1887
|
-
constructor(options = {}) {
|
|
1888
|
-
__publicField(this, "events", new RendererEventRegistry());
|
|
1889
|
-
__publicField(this, "pendingRequests", /* @__PURE__ */ new Map());
|
|
1890
|
-
__publicField(this, "requestPort");
|
|
1891
|
-
__publicField(this, "socketPort");
|
|
1892
|
-
__publicField(this, "senderId");
|
|
1893
|
-
__publicField(this, "bridge");
|
|
1894
|
-
__publicField(this, "initMessageType");
|
|
1895
|
-
__publicField(this, "windowRef");
|
|
1896
|
-
__publicField(this, "generateRequestId");
|
|
1897
|
-
__publicField(this, "isReady", false);
|
|
1898
|
-
__publicField(this, "setupPromise");
|
|
1899
|
-
__publicField(this, "setupResolve");
|
|
1900
|
-
__publicField(this, "setupReject");
|
|
1901
|
-
__publicField(this, "onWindowMessage", /* @__PURE__ */ __name((event) => {
|
|
1902
|
-
if (event.data?.type !== this.initMessageType) {
|
|
1903
|
-
return;
|
|
1904
|
-
}
|
|
1905
|
-
if (!Array.isArray(event.ports) || event.ports.length < 2) {
|
|
1906
|
-
const error = new Error("[Noxus] Renderer expected two MessagePorts (request + socket).");
|
|
1907
|
-
console.error(error);
|
|
1908
|
-
this.setupReject?.(error);
|
|
1909
|
-
this.resetSetupState();
|
|
1910
|
-
return;
|
|
1911
|
-
}
|
|
1912
|
-
this.windowRef.removeEventListener("message", this.onWindowMessage);
|
|
1913
|
-
this.requestPort = event.ports[0];
|
|
1914
|
-
this.socketPort = event.ports[1];
|
|
1915
|
-
this.senderId = event.data.senderId;
|
|
1916
|
-
if (this.requestPort === void 0 || this.socketPort === void 0) {
|
|
1917
|
-
const error = new Error("[Noxus] Renderer failed to receive valid MessagePorts.");
|
|
1918
|
-
console.error(error);
|
|
1919
|
-
this.setupReject?.(error);
|
|
1920
|
-
this.resetSetupState();
|
|
1921
|
-
return;
|
|
1922
|
-
}
|
|
1923
|
-
this.attachRequestPort(this.requestPort);
|
|
1924
|
-
this.attachSocketPort(this.socketPort);
|
|
1925
|
-
this.isReady = true;
|
|
1926
|
-
this.setupResolve?.();
|
|
1927
|
-
this.resetSetupState(true);
|
|
1928
|
-
}, "onWindowMessage"));
|
|
1929
|
-
__publicField(this, "onSocketMessage", /* @__PURE__ */ __name((event) => {
|
|
1930
|
-
if (this.events.tryDispatchFromMessageEvent(event)) {
|
|
1931
|
-
return;
|
|
1932
|
-
}
|
|
1933
|
-
console.warn("[Noxus] Received a socket message that is not a renderer event payload.", event.data);
|
|
1934
|
-
}, "onSocketMessage"));
|
|
1935
|
-
__publicField(this, "onRequestMessage", /* @__PURE__ */ __name((event) => {
|
|
1936
|
-
if (this.events.tryDispatchFromMessageEvent(event)) {
|
|
1937
|
-
return;
|
|
1938
|
-
}
|
|
1939
|
-
const response = event.data;
|
|
1940
|
-
if (!response || typeof response.requestId !== "string") {
|
|
1941
|
-
console.error("[Noxus] Renderer received an invalid response payload.", response);
|
|
1942
|
-
return;
|
|
1943
|
-
}
|
|
1944
|
-
const pending = this.pendingRequests.get(response.requestId);
|
|
1945
|
-
if (!pending) {
|
|
1946
|
-
console.error(`[Noxus] No pending handler found for request ${response.requestId}.`);
|
|
1947
|
-
return;
|
|
1948
|
-
}
|
|
1949
|
-
this.pendingRequests.delete(response.requestId);
|
|
1950
|
-
this.onRequestCompleted(pending, response);
|
|
1951
|
-
if (response.status >= 400) {
|
|
1952
|
-
pending.reject(response);
|
|
1953
|
-
return;
|
|
1954
|
-
}
|
|
1955
|
-
pending.resolve(response.body);
|
|
1956
|
-
}, "onRequestMessage"));
|
|
1957
|
-
this.windowRef = options.windowRef ?? window;
|
|
1958
|
-
const resolvedBridge = options.bridge ?? resolveBridgeFromWindow(this.windowRef, options.bridgeName);
|
|
1959
|
-
this.bridge = resolvedBridge ?? null;
|
|
1960
|
-
this.initMessageType = options.initMessageType ?? DEFAULT_INIT_EVENT2;
|
|
1961
|
-
this.generateRequestId = options.generateRequestId ?? defaultRequestId;
|
|
1962
|
-
}
|
|
1963
|
-
async setup() {
|
|
1964
|
-
if (this.isReady) {
|
|
1965
|
-
return Promise.resolve();
|
|
1966
|
-
}
|
|
1967
|
-
if (this.setupPromise) {
|
|
1968
|
-
return this.setupPromise;
|
|
1969
|
-
}
|
|
1970
|
-
if (!this.bridge || typeof this.bridge.requestPort !== "function") {
|
|
1971
|
-
throw new Error("[Noxus] Renderer bridge is missing requestPort().");
|
|
1972
|
-
}
|
|
1973
|
-
this.setupPromise = new Promise((resolve, reject) => {
|
|
1974
|
-
this.setupResolve = resolve;
|
|
1975
|
-
this.setupReject = reject;
|
|
1976
|
-
});
|
|
1977
|
-
this.windowRef.addEventListener("message", this.onWindowMessage);
|
|
1978
|
-
this.bridge.requestPort();
|
|
1979
|
-
return this.setupPromise;
|
|
1980
|
-
}
|
|
1981
|
-
dispose() {
|
|
1982
|
-
this.windowRef.removeEventListener("message", this.onWindowMessage);
|
|
1983
|
-
this.requestPort?.close();
|
|
1984
|
-
this.socketPort?.close();
|
|
1985
|
-
this.requestPort = void 0;
|
|
1986
|
-
this.socketPort = void 0;
|
|
1987
|
-
this.senderId = void 0;
|
|
1988
|
-
this.isReady = false;
|
|
1989
|
-
this.pendingRequests.clear();
|
|
1990
|
-
}
|
|
1991
|
-
async request(request) {
|
|
1992
|
-
const senderId = this.senderId;
|
|
1993
|
-
const requestId = this.generateRequestId();
|
|
1994
|
-
if (senderId === void 0) {
|
|
1995
|
-
return Promise.reject(this.createErrorResponse(requestId, "MessagePort is not available"));
|
|
1996
|
-
}
|
|
1997
|
-
const readinessError = this.validateReady(requestId);
|
|
1998
|
-
if (readinessError) {
|
|
1999
|
-
return Promise.reject(readinessError);
|
|
2000
|
-
}
|
|
2001
|
-
const message = {
|
|
2002
|
-
requestId,
|
|
2003
|
-
senderId,
|
|
2004
|
-
...request
|
|
2005
|
-
};
|
|
2006
|
-
return new Promise((resolve, reject) => {
|
|
2007
|
-
const pending = {
|
|
2008
|
-
resolve,
|
|
2009
|
-
reject: /* @__PURE__ */ __name((response) => reject(response), "reject"),
|
|
2010
|
-
request: message,
|
|
2011
|
-
submittedAt: Date.now()
|
|
2012
|
-
};
|
|
2013
|
-
this.pendingRequests.set(message.requestId, pending);
|
|
2014
|
-
this.requestPort.postMessage(message);
|
|
2015
|
-
});
|
|
2016
|
-
}
|
|
2017
|
-
async batch(requests) {
|
|
2018
|
-
return this.request({
|
|
2019
|
-
method: "BATCH",
|
|
2020
|
-
path: "",
|
|
2021
|
-
body: {
|
|
2022
|
-
requests
|
|
2023
|
-
}
|
|
2024
|
-
});
|
|
2025
|
-
}
|
|
2026
|
-
getSenderId() {
|
|
2027
|
-
return this.senderId;
|
|
2028
|
-
}
|
|
2029
|
-
onRequestCompleted(pending, response) {
|
|
2030
|
-
if (typeof console.groupCollapsed === "function") {
|
|
2031
|
-
console.groupCollapsed(`${response.status} ${pending.request.method} /${pending.request.path}`);
|
|
2032
|
-
}
|
|
2033
|
-
if (response.error) {
|
|
2034
|
-
console.error("error message:", response.error);
|
|
2035
|
-
}
|
|
2036
|
-
if (response.body !== void 0) {
|
|
2037
|
-
console.info("response:", response.body);
|
|
2038
|
-
}
|
|
2039
|
-
console.info("request:", pending.request);
|
|
2040
|
-
console.info(`Request duration: ${Date.now() - pending.submittedAt} ms`);
|
|
2041
|
-
if (typeof console.groupCollapsed === "function") {
|
|
2042
|
-
console.groupEnd();
|
|
2043
|
-
}
|
|
2044
|
-
}
|
|
2045
|
-
attachRequestPort(port) {
|
|
2046
|
-
port.onmessage = this.onRequestMessage;
|
|
2047
|
-
port.start();
|
|
2048
|
-
}
|
|
2049
|
-
attachSocketPort(port) {
|
|
2050
|
-
port.onmessage = this.onSocketMessage;
|
|
2051
|
-
port.start();
|
|
2052
|
-
}
|
|
2053
|
-
validateReady(requestId) {
|
|
2054
|
-
if (!this.isElectronEnvironment()) {
|
|
2055
|
-
return this.createErrorResponse(requestId, "Not running in Electron environment");
|
|
2056
|
-
}
|
|
2057
|
-
if (!this.requestPort) {
|
|
2058
|
-
return this.createErrorResponse(requestId, "MessagePort is not available");
|
|
2059
|
-
}
|
|
2060
|
-
return void 0;
|
|
2061
|
-
}
|
|
2062
|
-
createErrorResponse(requestId, message) {
|
|
2063
|
-
return {
|
|
2064
|
-
status: 500,
|
|
2065
|
-
requestId,
|
|
2066
|
-
error: message
|
|
2067
|
-
};
|
|
2068
|
-
}
|
|
2069
|
-
resetSetupState(success = false) {
|
|
2070
|
-
if (!success) {
|
|
2071
|
-
this.setupPromise = void 0;
|
|
2072
|
-
}
|
|
2073
|
-
this.setupResolve = void 0;
|
|
2074
|
-
this.setupReject = void 0;
|
|
2075
|
-
}
|
|
2076
|
-
isElectronEnvironment() {
|
|
2077
|
-
return typeof window !== "undefined" && /Electron/.test(window.navigator.userAgent);
|
|
2078
|
-
}
|
|
2079
|
-
};
|
|
2080
|
-
__name(_NoxRendererClient, "NoxRendererClient");
|
|
2081
|
-
var NoxRendererClient = _NoxRendererClient;
|
|
2082
1867
|
export {
|
|
2083
1868
|
AppInjector,
|
|
2084
1869
|
Authorize,
|
|
@@ -2111,7 +1896,6 @@ export {
|
|
|
2111
1896
|
NotFoundException,
|
|
2112
1897
|
NotImplementedException,
|
|
2113
1898
|
NoxApp,
|
|
2114
|
-
NoxRendererClient,
|
|
2115
1899
|
NoxSocket,
|
|
2116
1900
|
Patch,
|
|
2117
1901
|
PaymentRequiredException,
|
|
@@ -2119,7 +1903,6 @@ export {
|
|
|
2119
1903
|
Put,
|
|
2120
1904
|
RENDERER_EVENT_TYPE,
|
|
2121
1905
|
ROUTE_METADATA_KEY,
|
|
2122
|
-
RendererEventRegistry,
|
|
2123
1906
|
Request,
|
|
2124
1907
|
RequestTimeoutException,
|
|
2125
1908
|
ResponseException,
|
|
@@ -2133,7 +1916,6 @@ export {
|
|
|
2133
1916
|
VariantAlsoNegotiatesException,
|
|
2134
1917
|
bootstrapApplication,
|
|
2135
1918
|
createRendererEventMessage,
|
|
2136
|
-
exposeNoxusBridge,
|
|
2137
1919
|
forwardRef,
|
|
2138
1920
|
getControllerMetadata,
|
|
2139
1921
|
getGuardForController,
|