@noxfly/noxus 1.2.0 → 2.0.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/.github/copilot-instructions.md +32 -0
- package/README.md +36 -127
- package/dist/{index-5OkVPHfI.d.mts → index-CI3OMzNR.d.mts} +52 -2
- package/dist/{index-5OkVPHfI.d.ts → index-CI3OMzNR.d.ts} +52 -2
- package/dist/main.d.mts +34 -14
- package/dist/main.d.ts +34 -14
- package/dist/main.js +342 -31
- package/dist/main.mjs +339 -31
- package/dist/renderer.d.mts +1 -1
- package/dist/renderer.d.ts +1 -1
- package/dist/renderer.js +251 -1
- package/dist/renderer.mjs +250 -1
- package/package.json +1 -1
- package/src/DI/injector-explorer.ts +1 -1
- package/src/app.ts +24 -15
- package/src/decorators/injectable.decorator.ts +6 -17
- package/src/decorators/injectable.metadata.ts +15 -0
- package/src/index.ts +1 -0
- package/src/main.ts +3 -0
- package/src/preload-bridge.ts +75 -0
- package/src/renderer-client.ts +338 -0
- package/src/request.ts +1 -0
- package/src/router.ts +1 -1
- package/src/socket.ts +14 -9
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Copilot Instructions
|
|
2
|
+
## Core Architecture
|
|
3
|
+
- bootstrapApplication in [src/bootstrap.ts](src/bootstrap.ts) waits for Electron app readiness, resolves NoxApp via DI, and returns a configured instance.
|
|
4
|
+
- [src/app.ts](src/app.ts) wires ipcMain events, spawns paired request/socket MessageChannels per renderer, and delegates handling to Router and NoxSocket.
|
|
5
|
+
- Package exports are split between renderer and main targets in [package.json](package.json); import Electron main APIs from @noxfly/noxus/main and renderer helpers from @noxfly/noxus or @noxfly/noxus/renderer.
|
|
6
|
+
- Dependency injection centers on RootInjector in [src/DI/app-injector.ts](src/DI/app-injector.ts); @Injectable triggers auto-registration through [src/DI/injector-explorer.ts](src/DI/injector-explorer.ts) and supports singleton, scope, and transient lifetimes.
|
|
7
|
+
- Modules decorated via [src/decorators/module.decorator.ts](src/decorators/module.decorator.ts) compose providers, controllers, and nested modules; bootstrapApplication rejects roots lacking Module metadata.
|
|
8
|
+
## Request Lifecycle
|
|
9
|
+
- Request objects from [src/request.ts](src/request.ts) wrap Electron MessageEvents and spawn per-request DI scopes on Request.context.
|
|
10
|
+
- Router in [src/router.ts](src/router.ts) indexes routes in a radix tree, merges controller-level and method-level decorators, and enforces root middlewares, route middlewares, then guards before invoking controller actions.
|
|
11
|
+
- ResponseException subclasses in [src/exceptions.ts](src/exceptions.ts) propagate status codes; throwing one short-circuits the pipeline so Router returns a structured error payload.
|
|
12
|
+
- Batch requests use HTTP method BATCH and normalization logic in Router.handleBatch; payloads must satisfy IBatchRequestPayload to fan out atomic subrequests.
|
|
13
|
+
## Communication Channels
|
|
14
|
+
- ipcMain listens for gimme-my-port and posts two transferable ports back to the renderer: index 0 carries request/response traffic, index 1 is reserved for socket-style push messages.
|
|
15
|
+
- NoxSocket in [src/socket.ts](src/socket.ts) maps sender IDs to {request, socket} channels and emits renderer events exclusively through channels.socket.port1.
|
|
16
|
+
- Renderer helpers in [src/renderer-events.ts](src/renderer-events.ts) expose RendererEventRegistry.tryDispatchFromMessageEvent to route push events; the preload script must start both ports and hand the second to this registry.
|
|
17
|
+
- Renderer-facing bootstrap lives in [src/renderer-client.ts](src/renderer-client.ts); NoxRendererClient requests ports, wires request/socket handlers, tracks pending promises, and surfaces RendererEventRegistry for push consumption.
|
|
18
|
+
- Preload scripts should call exposeNoxusBridge from [src/preload-bridge.ts](src/preload-bridge.ts) to publish window.noxus.requestPort; the helper sends 'gimme-my-port' and forwards both transferable ports with the configured init message.
|
|
19
|
+
- When adjusting preload or renderer glue, ensure window.postMessage('init-port', ...) forwards both ports so the socket channel stays alive alongside the request channel.
|
|
20
|
+
## Decorator Conventions
|
|
21
|
+
- Controller paths omit leading/trailing slashes; method decorators (Get, Post, etc.) auto-trim segments via [src/decorators/method.decorator.ts](src/decorators/method.decorator.ts).
|
|
22
|
+
- Guards registered through Authorize in [src/decorators/guards.decorator.ts](src/decorators/guards.decorator.ts) aggregate at controller and action scope; they must resolve truthy or Router throws UnauthorizedException.
|
|
23
|
+
- Injectable lifetimes default to scope; use singleton for app-wide utilities (window managers, sockets) and transient for short-lived resources.
|
|
24
|
+
## Logging and Utilities
|
|
25
|
+
- Logger in [src/utils/logger.ts](src/utils/logger.ts) standardizes color-coded log, warn, error, and comment output; use it when extending framework behavior.
|
|
26
|
+
- Path resolution relies on RadixTree from [src/utils/radix-tree.ts](src/utils/radix-tree.ts); normalize controller and route paths to avoid duplicate slashes.
|
|
27
|
+
- Request.params are filled by Router.extractParams; controllers read route params directly from Request without decorator helpers yet.
|
|
28
|
+
## Build and Tooling
|
|
29
|
+
- Run npm run build to invoke tsup with dual ESM/CJS outputs configured in [tsup.config.ts](tsup.config.ts); the postbuild script at [scripts/postbuild.js](scripts/postbuild.js) deduplicates license banners.
|
|
30
|
+
- Node 20 or newer is required; reflect-metadata is a peer dependency so host apps must install and import it before using decorators.
|
|
31
|
+
- Source uses baseUrl ./ with tsc-alias, so prefer absolute imports like src/module/file when editing framework code to match existing style.
|
|
32
|
+
- Dist artifacts live under dist/ and are published outputs; regenerate them via the build script rather than editing directly.
|
package/README.md
CHANGED
|
@@ -34,20 +34,12 @@ Noxus fills that gap.
|
|
|
34
34
|
|
|
35
35
|
## Installation
|
|
36
36
|
|
|
37
|
-
Install the package in your main process application :
|
|
37
|
+
Install the package in your main process application, and in your renderer as well :
|
|
38
38
|
|
|
39
39
|
```sh
|
|
40
40
|
npm i @noxfly/noxus
|
|
41
41
|
```
|
|
42
42
|
|
|
43
|
-
If you have a separated renderer from the main process, you'd like to install the package as well to get typed requests/responses models, for development purposes :
|
|
44
|
-
|
|
45
|
-
```sh
|
|
46
|
-
npm i -D @noxfly/noxus
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
Because you only need types during development, using the `-D` argument will make this package a `devDependency`, thus won't be present on your build.
|
|
50
|
-
|
|
51
43
|
> ⚠️ The default entry (`@noxfly/noxus`) only exposes renderer-friendly helpers and types. Import Electron main-process APIs from `@noxfly/noxus/main`.
|
|
52
44
|
|
|
53
45
|
## Basic use
|
|
@@ -202,145 +194,62 @@ We need some configuration on the preload so the main process can give the rende
|
|
|
202
194
|
```ts
|
|
203
195
|
// main/preload.ts
|
|
204
196
|
|
|
205
|
-
import {
|
|
206
|
-
|
|
207
|
-
// .invoke -> front sends to back
|
|
208
|
-
// .on -> back sends to front
|
|
209
|
-
|
|
210
|
-
type fn = (...args: any[]) => void;
|
|
197
|
+
import { exposeNoxusBridge } from '@noxfly/noxus';
|
|
211
198
|
|
|
212
|
-
|
|
213
|
-
requestPort: () => ipcRenderer.send('gimme-my-port'),
|
|
214
|
-
|
|
215
|
-
hereIsMyPort: () => ipcRenderer.once('port', (e, message) => {
|
|
216
|
-
e.ports[0]?.start();
|
|
217
|
-
window.postMessage({ type: 'init-port', senderId: message.senderId }, '*', [e.ports[0]!]);
|
|
218
|
-
}),
|
|
219
|
-
});
|
|
199
|
+
exposeNoxusBridge();
|
|
220
200
|
```
|
|
221
201
|
|
|
222
|
-
|
|
202
|
+
The helper uses `ipcRenderer.send('gimme-my-port')`, waits for the `'port'` response, starts both transferred `MessagePort`s, and forwards them to the renderer with `window.postMessage({ type: 'init-port', ... }, '*', [requestPort, socketPort])`. If you need to customise any channel names or the exposed property, pass `exposeNoxusBridge({ exposeAs: 'customNoxus', requestChannel: 'my-port', responseChannel: 'my-port-ready', initMessageType: 'custom-init' })`.
|
|
223
203
|
|
|
224
|
-
|
|
204
|
+
> ⚠️ As the Electron documentation warns, never expose the full `ipcRenderer` object. The helper only reveals a minimal `{ requestPort }` surface under `window.noxus` by default.
|
|
225
205
|
|
|
226
206
|
|
|
227
207
|
### Setup Renderer
|
|
228
208
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
Maybe this should become a class directly available from @noxfly/noxus;
|
|
209
|
+
Noxus ships with a `NoxRendererClient` helper that performs the renderer bootstrap: it asks the preload bridge for a port, expects two transferable `MessagePort`s (index `0` for request/response and index `1` for socket pushes), wires both, and exposes a promise-based `request`/`batch` API plus the `RendererEventRegistry` instance.
|
|
232
210
|
|
|
233
|
-
|
|
234
|
-
// renderer/anyFileAtStartup.ts
|
|
211
|
+
By default it calls `window.noxus.requestPort()`—the value registered by `exposeNoxusBridge()`—but you can pass a custom bridge through the constructor options if needed.
|
|
235
212
|
|
|
236
|
-
|
|
213
|
+
Call `await client.setup()` early in your renderer startup (for example inside the first Angular service that needs IPC). Once the promise resolves, `client.request(...)` automatically includes the negotiated `senderId`, and socket events are routed through `client.events`.
|
|
237
214
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
this.bridge = window as any;
|
|
255
|
-
this.ipcRenderer = this.bridge.ipcRenderer;
|
|
256
|
-
|
|
257
|
-
// when receiving the port given by the main renderer -> preload -> renderer
|
|
258
|
-
window.addEventListener('message', (event: MessageEvent) => {
|
|
259
|
-
if(event.data?.type === 'init-port' && event.ports.length > 0) {
|
|
260
|
-
this.port = event.ports[0]!;
|
|
261
|
-
this.senderId = event.data.senderId;
|
|
262
|
-
this.port.onmessage = onResponse;
|
|
263
|
-
}
|
|
264
|
-
});
|
|
265
|
-
|
|
266
|
-
ipcRenderer.requestPort();
|
|
215
|
+
```ts
|
|
216
|
+
// renderer/services/noxus.service.ts
|
|
217
|
+
|
|
218
|
+
import { Injectable } from '@angular/core';
|
|
219
|
+
import { from, Observable } from 'rxjs';
|
|
220
|
+
import {
|
|
221
|
+
IBatchRequestItem,
|
|
222
|
+
IBatchResponsePayload,
|
|
223
|
+
IRequest,
|
|
224
|
+
NoxRendererClient,
|
|
225
|
+
} from '@noxfly/noxus';
|
|
226
|
+
|
|
227
|
+
@Injectable({ providedIn: 'root' })
|
|
228
|
+
export class NoxusService extends NoxRendererClient {
|
|
229
|
+
public async init(): Promise<void> {
|
|
230
|
+
await this.setup();
|
|
267
231
|
}
|
|
268
232
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
*/
|
|
272
|
-
private onResponse(event: MessageEvent): void {
|
|
273
|
-
const response: IResponse<unknown> = event.data;
|
|
274
|
-
|
|
275
|
-
if(!response || !response.requestId) {
|
|
276
|
-
console.error('Received invalid response:', response);
|
|
277
|
-
return;
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
const pending = this.pendingRequests.get(response.requestId);
|
|
281
|
-
|
|
282
|
-
if(!pending) {
|
|
283
|
-
console.error(`No handler found for request ID: ${response.requestId}`);
|
|
284
|
-
return;
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
this.pendingRequests.delete(response.requestId);
|
|
288
|
-
|
|
289
|
-
let fn: (response: IResponse<unknown>) => void = pending.resolve;
|
|
290
|
-
|
|
291
|
-
console.groupCollapsed(`${response.status} ${pending.request.method} /${pending.request.path}`);
|
|
292
|
-
|
|
293
|
-
if(response.error) {
|
|
294
|
-
console.error('error message:', response.error);
|
|
295
|
-
fn = pending.reject;
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
console.info('response:', response.body);
|
|
299
|
-
console.info('request:', pending.request);
|
|
300
|
-
|
|
301
|
-
console.groupEnd();
|
|
302
|
-
|
|
303
|
-
fn(response);
|
|
233
|
+
public request$<T, U = unknown>(request: Omit<IRequest<U>, 'requestId' | 'senderId'>): Observable<T> {
|
|
234
|
+
return from(this.request<T, U>(request));
|
|
304
235
|
}
|
|
305
236
|
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
*/
|
|
309
|
-
public request<T>(request: Omit<IRequest, 'requestId' | 'senderId'>): Promise<T> {
|
|
310
|
-
return new Promise<T>((resolve, reject) => {
|
|
311
|
-
if(!this.port || !this.senderId) {
|
|
312
|
-
return reject(new Error("MessagePort is not available"));
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
const req: IRequest = {
|
|
316
|
-
requestId: /* Create a random ID with the function of your choice */,
|
|
317
|
-
senderId: this.senderId,
|
|
318
|
-
...request,
|
|
319
|
-
};
|
|
320
|
-
|
|
321
|
-
this.pendingRequests.set(req.requestId, {
|
|
322
|
-
resolve: (response: IResponse<T>) => (response.status < 400)
|
|
323
|
-
? resolve(response.body as T)
|
|
324
|
-
: reject(response);
|
|
325
|
-
reject: (response?: IResponse<T>) => reject(response),
|
|
326
|
-
request: req,
|
|
327
|
-
});
|
|
328
|
-
|
|
329
|
-
this.port.postMessage(req);
|
|
330
|
-
});
|
|
237
|
+
public batch$<T = IBatchResponsePayload>(requests: Omit<IBatchRequestItem<unknown>, 'requestId'>[]): Observable<T> {
|
|
238
|
+
return from(this.batch(requests) as Promise<T>);
|
|
331
239
|
}
|
|
332
240
|
}
|
|
333
|
-
```
|
|
334
241
|
|
|
335
|
-
|
|
242
|
+
// Somewhere during app bootstrap
|
|
243
|
+
await noxusService.init();
|
|
336
244
|
|
|
337
|
-
|
|
338
|
-
const
|
|
339
|
-
|
|
340
|
-
path: 'users/all',
|
|
245
|
+
// Subscribe to push notifications
|
|
246
|
+
const subscription = noxusService.events.subscribe('users.updated', (payload) => {
|
|
247
|
+
console.log('Users updated:', payload);
|
|
341
248
|
});
|
|
342
249
|
```
|
|
343
250
|
|
|
251
|
+
If you need a custom bridge (for example a different preload shape), pass it via the constructor: `super({ bridge: window.customBridge })`. The class keeps promise-based semantics so frameworks can layer their own reactive wrappers as shown above.
|
|
252
|
+
|
|
344
253
|

|
|
345
254
|
|
|
346
255
|
|
|
@@ -354,7 +263,7 @@ If you throw any of these exception, the response to the renderer will contains
|
|
|
354
263
|
|
|
355
264
|
You can specify a message in the constructor.
|
|
356
265
|
|
|
357
|
-
You throw it as follow :
|
|
266
|
+
You throw it as follow :
|
|
358
267
|
```ts
|
|
359
268
|
throw new UnauthorizedException("Invalid credentials");
|
|
360
269
|
throw new BadRequestException("id is missing in the body");
|
|
@@ -176,13 +176,14 @@ declare const RootInjector: AppInjector;
|
|
|
176
176
|
*/
|
|
177
177
|
declare class Request {
|
|
178
178
|
readonly event: Electron.MessageEvent;
|
|
179
|
+
readonly senderId: number;
|
|
179
180
|
readonly id: string;
|
|
180
181
|
readonly method: HttpMethod;
|
|
181
182
|
readonly path: string;
|
|
182
183
|
readonly body: any;
|
|
183
184
|
readonly context: AppInjector;
|
|
184
185
|
readonly params: Record<string, string>;
|
|
185
|
-
constructor(event: Electron.MessageEvent, id: string, method: HttpMethod, path: string, body: any);
|
|
186
|
+
constructor(event: Electron.MessageEvent, senderId: number, id: string, method: HttpMethod, path: string, body: any);
|
|
186
187
|
}
|
|
187
188
|
/**
|
|
188
189
|
* The IRequest interface defines the structure of a request object.
|
|
@@ -265,4 +266,53 @@ declare class RendererEventRegistry {
|
|
|
265
266
|
hasHandlers(eventName: string): boolean;
|
|
266
267
|
}
|
|
267
268
|
|
|
268
|
-
|
|
269
|
+
|
|
270
|
+
interface IPortRequester {
|
|
271
|
+
requestPort(): void;
|
|
272
|
+
}
|
|
273
|
+
interface RendererClientOptions {
|
|
274
|
+
bridge?: IPortRequester | null;
|
|
275
|
+
bridgeName?: string | string[];
|
|
276
|
+
initMessageType?: string;
|
|
277
|
+
windowRef?: Window;
|
|
278
|
+
generateRequestId?: () => string;
|
|
279
|
+
}
|
|
280
|
+
interface PendingRequest<T = unknown> {
|
|
281
|
+
resolve: (value: T) => void;
|
|
282
|
+
reject: (reason: IResponse<T>) => void;
|
|
283
|
+
request: IRequest;
|
|
284
|
+
submittedAt: number;
|
|
285
|
+
}
|
|
286
|
+
declare class NoxRendererClient {
|
|
287
|
+
readonly events: RendererEventRegistry;
|
|
288
|
+
protected readonly pendingRequests: Map<string, PendingRequest<unknown>>;
|
|
289
|
+
protected requestPort: MessagePort | undefined;
|
|
290
|
+
protected socketPort: MessagePort | undefined;
|
|
291
|
+
protected senderId: number | undefined;
|
|
292
|
+
private readonly bridge;
|
|
293
|
+
private readonly initMessageType;
|
|
294
|
+
private readonly windowRef;
|
|
295
|
+
private readonly generateRequestId;
|
|
296
|
+
private isReady;
|
|
297
|
+
private setupPromise;
|
|
298
|
+
private setupResolve;
|
|
299
|
+
private setupReject;
|
|
300
|
+
constructor(options?: RendererClientOptions);
|
|
301
|
+
setup(): Promise<void>;
|
|
302
|
+
dispose(): void;
|
|
303
|
+
request<TResponse, TBody = unknown>(request: Omit<IRequest<TBody>, 'requestId' | 'senderId'>): Promise<TResponse>;
|
|
304
|
+
batch(requests: Omit<IBatchRequestItem<unknown>, 'requestId'>[]): Promise<IBatchResponsePayload>;
|
|
305
|
+
getSenderId(): number | undefined;
|
|
306
|
+
private readonly onWindowMessage;
|
|
307
|
+
private readonly onSocketMessage;
|
|
308
|
+
private readonly onRequestMessage;
|
|
309
|
+
protected onRequestCompleted(pending: PendingRequest, response: IResponse): void;
|
|
310
|
+
private attachRequestPort;
|
|
311
|
+
private attachSocketPort;
|
|
312
|
+
private validateReady;
|
|
313
|
+
private createErrorResponse;
|
|
314
|
+
private resetSetupState;
|
|
315
|
+
isElectronEnvironment(): boolean;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
export { AppInjector as A, Delete as D, Get as G, type HttpMethod as H, type IResponse as I, type Lifetime as L, type MaybeAsync as M, NoxRendererClient as N, Post as P, Request as R, type Type as T, type IGuard as a, type IPortRequester as b, type IBinding as c, RootInjector as d, Authorize as e, getGuardForControllerAction as f, getGuardForController as g, type IRouteMetadata as h, inject as i, type AtomicHttpMethod as j, getRouteMetadata as k, Put as l, Patch as m, ROUTE_METADATA_KEY as n, type IRequest as o, type IBatchRequestItem as p, type IBatchRequestPayload as q, type IBatchResponsePayload as r, RENDERER_EVENT_TYPE as s, type IRendererEventMessage as t, createRendererEventMessage as u, isRendererEventMessage as v, type RendererEventHandler as w, type RendererEventSubscription as x, RendererEventRegistry as y, type RendererClientOptions as z };
|
|
@@ -176,13 +176,14 @@ declare const RootInjector: AppInjector;
|
|
|
176
176
|
*/
|
|
177
177
|
declare class Request {
|
|
178
178
|
readonly event: Electron.MessageEvent;
|
|
179
|
+
readonly senderId: number;
|
|
179
180
|
readonly id: string;
|
|
180
181
|
readonly method: HttpMethod;
|
|
181
182
|
readonly path: string;
|
|
182
183
|
readonly body: any;
|
|
183
184
|
readonly context: AppInjector;
|
|
184
185
|
readonly params: Record<string, string>;
|
|
185
|
-
constructor(event: Electron.MessageEvent, id: string, method: HttpMethod, path: string, body: any);
|
|
186
|
+
constructor(event: Electron.MessageEvent, senderId: number, id: string, method: HttpMethod, path: string, body: any);
|
|
186
187
|
}
|
|
187
188
|
/**
|
|
188
189
|
* The IRequest interface defines the structure of a request object.
|
|
@@ -265,4 +266,53 @@ declare class RendererEventRegistry {
|
|
|
265
266
|
hasHandlers(eventName: string): boolean;
|
|
266
267
|
}
|
|
267
268
|
|
|
268
|
-
|
|
269
|
+
|
|
270
|
+
interface IPortRequester {
|
|
271
|
+
requestPort(): void;
|
|
272
|
+
}
|
|
273
|
+
interface RendererClientOptions {
|
|
274
|
+
bridge?: IPortRequester | null;
|
|
275
|
+
bridgeName?: string | string[];
|
|
276
|
+
initMessageType?: string;
|
|
277
|
+
windowRef?: Window;
|
|
278
|
+
generateRequestId?: () => string;
|
|
279
|
+
}
|
|
280
|
+
interface PendingRequest<T = unknown> {
|
|
281
|
+
resolve: (value: T) => void;
|
|
282
|
+
reject: (reason: IResponse<T>) => void;
|
|
283
|
+
request: IRequest;
|
|
284
|
+
submittedAt: number;
|
|
285
|
+
}
|
|
286
|
+
declare class NoxRendererClient {
|
|
287
|
+
readonly events: RendererEventRegistry;
|
|
288
|
+
protected readonly pendingRequests: Map<string, PendingRequest<unknown>>;
|
|
289
|
+
protected requestPort: MessagePort | undefined;
|
|
290
|
+
protected socketPort: MessagePort | undefined;
|
|
291
|
+
protected senderId: number | undefined;
|
|
292
|
+
private readonly bridge;
|
|
293
|
+
private readonly initMessageType;
|
|
294
|
+
private readonly windowRef;
|
|
295
|
+
private readonly generateRequestId;
|
|
296
|
+
private isReady;
|
|
297
|
+
private setupPromise;
|
|
298
|
+
private setupResolve;
|
|
299
|
+
private setupReject;
|
|
300
|
+
constructor(options?: RendererClientOptions);
|
|
301
|
+
setup(): Promise<void>;
|
|
302
|
+
dispose(): void;
|
|
303
|
+
request<TResponse, TBody = unknown>(request: Omit<IRequest<TBody>, 'requestId' | 'senderId'>): Promise<TResponse>;
|
|
304
|
+
batch(requests: Omit<IBatchRequestItem<unknown>, 'requestId'>[]): Promise<IBatchResponsePayload>;
|
|
305
|
+
getSenderId(): number | undefined;
|
|
306
|
+
private readonly onWindowMessage;
|
|
307
|
+
private readonly onSocketMessage;
|
|
308
|
+
private readonly onRequestMessage;
|
|
309
|
+
protected onRequestCompleted(pending: PendingRequest, response: IResponse): void;
|
|
310
|
+
private attachRequestPort;
|
|
311
|
+
private attachSocketPort;
|
|
312
|
+
private validateReady;
|
|
313
|
+
private createErrorResponse;
|
|
314
|
+
private resetSetupState;
|
|
315
|
+
isElectronEnvironment(): boolean;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
export { AppInjector as A, Delete as D, Get as G, type HttpMethod as H, type IResponse as I, type Lifetime as L, type MaybeAsync as M, NoxRendererClient as N, Post as P, Request as R, type Type as T, type IGuard as a, type IPortRequester as b, type IBinding as c, RootInjector as d, Authorize as e, getGuardForControllerAction as f, getGuardForController as g, type IRouteMetadata as h, inject as i, type AtomicHttpMethod as j, getRouteMetadata as k, Put as l, Patch as m, ROUTE_METADATA_KEY as n, type IRequest as o, type IBatchRequestItem as p, type IBatchRequestPayload as q, type IBatchResponsePayload as r, RENDERER_EVENT_TYPE as s, type IRendererEventMessage as t, createRendererEventMessage as u, isRendererEventMessage as v, type RendererEventHandler as w, type RendererEventSubscription as x, RendererEventRegistry as y, type RendererClientOptions as z };
|
package/dist/main.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { R as Request, I as IResponse, M as MaybeAsync, T as Type, a as IGuard, L as Lifetime } from './index-
|
|
2
|
-
export { A as AppInjector,
|
|
1
|
+
import { R as Request, I as IResponse, M as MaybeAsync, T as Type, a as IGuard, L as Lifetime, b as IPortRequester } from './index-CI3OMzNR.mjs';
|
|
2
|
+
export { A as AppInjector, j as AtomicHttpMethod, e as Authorize, D as Delete, G as Get, H as HttpMethod, p as IBatchRequestItem, q as IBatchRequestPayload, r as IBatchResponsePayload, c as IBinding, t as IRendererEventMessage, o as IRequest, h as IRouteMetadata, N as NoxRendererClient, m as Patch, P as Post, l as Put, s as RENDERER_EVENT_TYPE, n as ROUTE_METADATA_KEY, z as RendererClientOptions, w as RendererEventHandler, y as RendererEventRegistry, x as RendererEventSubscription, d as RootInjector, u as createRendererEventMessage, g as getGuardForController, f as getGuardForControllerAction, k as getRouteMetadata, i as inject, v as isRendererEventMessage } from './index-CI3OMzNR.mjs';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* @copyright 2025 NoxFly
|
|
@@ -160,10 +160,14 @@ declare class Router {
|
|
|
160
160
|
private extractParams;
|
|
161
161
|
}
|
|
162
162
|
|
|
163
|
+
interface RendererChannels {
|
|
164
|
+
request: Electron.MessageChannelMain;
|
|
165
|
+
socket: Electron.MessageChannelMain;
|
|
166
|
+
}
|
|
163
167
|
declare class NoxSocket {
|
|
164
|
-
private readonly
|
|
165
|
-
register(senderId: number,
|
|
166
|
-
get(senderId: number):
|
|
168
|
+
private readonly channels;
|
|
169
|
+
register(senderId: number, requestChannel: Electron.MessageChannelMain, socketChannel: Electron.MessageChannelMain): void;
|
|
170
|
+
get(senderId: number): RendererChannels | undefined;
|
|
167
171
|
unregister(senderId: number): void;
|
|
168
172
|
getSenderIds(): number[];
|
|
169
173
|
emit<TPayload = unknown>(eventName: string, payload?: TPayload, targetSenderIds?: number[]): number;
|
|
@@ -189,6 +193,9 @@ declare class NoxApp {
|
|
|
189
193
|
private readonly router;
|
|
190
194
|
private readonly socket;
|
|
191
195
|
private app;
|
|
196
|
+
/**
|
|
197
|
+
*
|
|
198
|
+
*/
|
|
192
199
|
private readonly onRendererMessage;
|
|
193
200
|
constructor(router: Router, socket: NoxSocket);
|
|
194
201
|
/**
|
|
@@ -352,6 +359,10 @@ declare function Controller(path: string): ClassDecorator;
|
|
|
352
359
|
declare function getControllerMetadata(target: Type<unknown>): IControllerMetadata | undefined;
|
|
353
360
|
declare const CONTROLLER_METADATA_KEY: unique symbol;
|
|
354
361
|
|
|
362
|
+
declare const INJECTABLE_METADATA_KEY: unique symbol;
|
|
363
|
+
declare function getInjectableMetadata(target: Function): Lifetime | undefined;
|
|
364
|
+
declare function hasInjectableMetadata(target: Function): boolean;
|
|
365
|
+
|
|
355
366
|
|
|
356
367
|
/**
|
|
357
368
|
* The Injectable decorator marks a class as injectable.
|
|
@@ -361,14 +372,6 @@ declare const CONTROLLER_METADATA_KEY: unique symbol;
|
|
|
361
372
|
* @param lifetime - The lifetime of the injectable. Can be 'singleton', 'scope', or 'transient'.
|
|
362
373
|
*/
|
|
363
374
|
declare function Injectable(lifetime?: Lifetime): ClassDecorator;
|
|
364
|
-
/**
|
|
365
|
-
* Gets the injectable metadata for a given target class.
|
|
366
|
-
* This metadata includes the lifetime of the injectable defined by the @Injectable decorator.
|
|
367
|
-
* @param target - The target class to get the injectable metadata from.
|
|
368
|
-
* @returns The lifetime of the injectable if it exists, otherwise undefined.
|
|
369
|
-
*/
|
|
370
|
-
declare function getInjectableMetadata(target: Type<unknown>): Lifetime | undefined;
|
|
371
|
-
declare const INJECTABLE_METADATA_KEY: unique symbol;
|
|
372
375
|
|
|
373
376
|
|
|
374
377
|
interface IModuleMetadata {
|
|
@@ -387,6 +390,23 @@ declare function Module(metadata: IModuleMetadata): ClassDecorator;
|
|
|
387
390
|
declare function getModuleMetadata(target: Function): IModuleMetadata | undefined;
|
|
388
391
|
declare const MODULE_METADATA_KEY: unique symbol;
|
|
389
392
|
|
|
393
|
+
|
|
394
|
+
interface NoxusPreloadAPI extends IPortRequester {
|
|
395
|
+
}
|
|
396
|
+
interface NoxusPreloadOptions {
|
|
397
|
+
exposeAs?: string;
|
|
398
|
+
initMessageType?: string;
|
|
399
|
+
requestChannel?: string;
|
|
400
|
+
responseChannel?: string;
|
|
401
|
+
targetWindow?: Window;
|
|
402
|
+
}
|
|
403
|
+
/**
|
|
404
|
+
* Exposes a minimal bridge in the isolated preload context so renderer processes
|
|
405
|
+
* can request the two MessagePorts required by Noxus. The bridge forwards both
|
|
406
|
+
* request/response and socket ports to the renderer via window.postMessage.
|
|
407
|
+
*/
|
|
408
|
+
declare function exposeNoxusBridge(options?: NoxusPreloadOptions): NoxusPreloadAPI;
|
|
409
|
+
|
|
390
410
|
/**
|
|
391
411
|
* Logger is a utility class for logging messages to the console.
|
|
392
412
|
*/
|
|
@@ -462,4 +482,4 @@ declare namespace Logger {
|
|
|
462
482
|
};
|
|
463
483
|
}
|
|
464
484
|
|
|
465
|
-
export { BadGatewayException, BadRequestException, CONTROLLER_METADATA_KEY, ConflictException, Controller, type ControllerAction, ForbiddenException, GatewayTimeoutException, HttpVersionNotSupportedException, type IApp, type IControllerMetadata, IGuard, type IMiddleware, type IModuleMetadata, INJECTABLE_METADATA_KEY, IResponse, type IRouteDefinition, Injectable, InsufficientStorageException, InternalServerException, Lifetime, type LogLevel, Logger, LoopDetectedException, MODULE_METADATA_KEY, MaybeAsync, MethodNotAllowedException, Module, NetworkAuthenticationRequiredException, NetworkConnectTimeoutException, type NextFunction, NotAcceptableException, NotExtendedException, NotFoundException, NotImplementedException, NoxApp, NoxSocket, PaymentRequiredException, Request, RequestTimeoutException, ResponseException, Router, ServiceUnavailableException, TooManyRequestsException, Type, UnauthorizedException, UpgradeRequiredException, UseMiddlewares, VariantAlsoNegotiatesException, bootstrapApplication, getControllerMetadata, getInjectableMetadata, getMiddlewaresForController, getMiddlewaresForControllerAction, getModuleMetadata };
|
|
485
|
+
export { BadGatewayException, BadRequestException, CONTROLLER_METADATA_KEY, ConflictException, Controller, type ControllerAction, ForbiddenException, GatewayTimeoutException, HttpVersionNotSupportedException, type IApp, type IControllerMetadata, IGuard, type IMiddleware, type IModuleMetadata, INJECTABLE_METADATA_KEY, IPortRequester, IResponse, type IRouteDefinition, Injectable, InsufficientStorageException, InternalServerException, Lifetime, type LogLevel, Logger, LoopDetectedException, MODULE_METADATA_KEY, MaybeAsync, MethodNotAllowedException, Module, NetworkAuthenticationRequiredException, NetworkConnectTimeoutException, type NextFunction, NotAcceptableException, NotExtendedException, NotFoundException, NotImplementedException, NoxApp, NoxSocket, type NoxusPreloadAPI, type NoxusPreloadOptions, PaymentRequiredException, Request, RequestTimeoutException, ResponseException, Router, ServiceUnavailableException, TooManyRequestsException, Type, UnauthorizedException, UpgradeRequiredException, UseMiddlewares, VariantAlsoNegotiatesException, bootstrapApplication, exposeNoxusBridge, getControllerMetadata, getInjectableMetadata, getMiddlewaresForController, getMiddlewaresForControllerAction, getModuleMetadata, hasInjectableMetadata };
|
package/dist/main.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { R as Request, I as IResponse, M as MaybeAsync, T as Type, a as IGuard, L as Lifetime } from './index-
|
|
2
|
-
export { A as AppInjector,
|
|
1
|
+
import { R as Request, I as IResponse, M as MaybeAsync, T as Type, a as IGuard, L as Lifetime, b as IPortRequester } from './index-CI3OMzNR.js';
|
|
2
|
+
export { A as AppInjector, j as AtomicHttpMethod, e as Authorize, D as Delete, G as Get, H as HttpMethod, p as IBatchRequestItem, q as IBatchRequestPayload, r as IBatchResponsePayload, c as IBinding, t as IRendererEventMessage, o as IRequest, h as IRouteMetadata, N as NoxRendererClient, m as Patch, P as Post, l as Put, s as RENDERER_EVENT_TYPE, n as ROUTE_METADATA_KEY, z as RendererClientOptions, w as RendererEventHandler, y as RendererEventRegistry, x as RendererEventSubscription, d as RootInjector, u as createRendererEventMessage, g as getGuardForController, f as getGuardForControllerAction, k as getRouteMetadata, i as inject, v as isRendererEventMessage } from './index-CI3OMzNR.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* @copyright 2025 NoxFly
|
|
@@ -160,10 +160,14 @@ declare class Router {
|
|
|
160
160
|
private extractParams;
|
|
161
161
|
}
|
|
162
162
|
|
|
163
|
+
interface RendererChannels {
|
|
164
|
+
request: Electron.MessageChannelMain;
|
|
165
|
+
socket: Electron.MessageChannelMain;
|
|
166
|
+
}
|
|
163
167
|
declare class NoxSocket {
|
|
164
|
-
private readonly
|
|
165
|
-
register(senderId: number,
|
|
166
|
-
get(senderId: number):
|
|
168
|
+
private readonly channels;
|
|
169
|
+
register(senderId: number, requestChannel: Electron.MessageChannelMain, socketChannel: Electron.MessageChannelMain): void;
|
|
170
|
+
get(senderId: number): RendererChannels | undefined;
|
|
167
171
|
unregister(senderId: number): void;
|
|
168
172
|
getSenderIds(): number[];
|
|
169
173
|
emit<TPayload = unknown>(eventName: string, payload?: TPayload, targetSenderIds?: number[]): number;
|
|
@@ -189,6 +193,9 @@ declare class NoxApp {
|
|
|
189
193
|
private readonly router;
|
|
190
194
|
private readonly socket;
|
|
191
195
|
private app;
|
|
196
|
+
/**
|
|
197
|
+
*
|
|
198
|
+
*/
|
|
192
199
|
private readonly onRendererMessage;
|
|
193
200
|
constructor(router: Router, socket: NoxSocket);
|
|
194
201
|
/**
|
|
@@ -352,6 +359,10 @@ declare function Controller(path: string): ClassDecorator;
|
|
|
352
359
|
declare function getControllerMetadata(target: Type<unknown>): IControllerMetadata | undefined;
|
|
353
360
|
declare const CONTROLLER_METADATA_KEY: unique symbol;
|
|
354
361
|
|
|
362
|
+
declare const INJECTABLE_METADATA_KEY: unique symbol;
|
|
363
|
+
declare function getInjectableMetadata(target: Function): Lifetime | undefined;
|
|
364
|
+
declare function hasInjectableMetadata(target: Function): boolean;
|
|
365
|
+
|
|
355
366
|
|
|
356
367
|
/**
|
|
357
368
|
* The Injectable decorator marks a class as injectable.
|
|
@@ -361,14 +372,6 @@ declare const CONTROLLER_METADATA_KEY: unique symbol;
|
|
|
361
372
|
* @param lifetime - The lifetime of the injectable. Can be 'singleton', 'scope', or 'transient'.
|
|
362
373
|
*/
|
|
363
374
|
declare function Injectable(lifetime?: Lifetime): ClassDecorator;
|
|
364
|
-
/**
|
|
365
|
-
* Gets the injectable metadata for a given target class.
|
|
366
|
-
* This metadata includes the lifetime of the injectable defined by the @Injectable decorator.
|
|
367
|
-
* @param target - The target class to get the injectable metadata from.
|
|
368
|
-
* @returns The lifetime of the injectable if it exists, otherwise undefined.
|
|
369
|
-
*/
|
|
370
|
-
declare function getInjectableMetadata(target: Type<unknown>): Lifetime | undefined;
|
|
371
|
-
declare const INJECTABLE_METADATA_KEY: unique symbol;
|
|
372
375
|
|
|
373
376
|
|
|
374
377
|
interface IModuleMetadata {
|
|
@@ -387,6 +390,23 @@ declare function Module(metadata: IModuleMetadata): ClassDecorator;
|
|
|
387
390
|
declare function getModuleMetadata(target: Function): IModuleMetadata | undefined;
|
|
388
391
|
declare const MODULE_METADATA_KEY: unique symbol;
|
|
389
392
|
|
|
393
|
+
|
|
394
|
+
interface NoxusPreloadAPI extends IPortRequester {
|
|
395
|
+
}
|
|
396
|
+
interface NoxusPreloadOptions {
|
|
397
|
+
exposeAs?: string;
|
|
398
|
+
initMessageType?: string;
|
|
399
|
+
requestChannel?: string;
|
|
400
|
+
responseChannel?: string;
|
|
401
|
+
targetWindow?: Window;
|
|
402
|
+
}
|
|
403
|
+
/**
|
|
404
|
+
* Exposes a minimal bridge in the isolated preload context so renderer processes
|
|
405
|
+
* can request the two MessagePorts required by Noxus. The bridge forwards both
|
|
406
|
+
* request/response and socket ports to the renderer via window.postMessage.
|
|
407
|
+
*/
|
|
408
|
+
declare function exposeNoxusBridge(options?: NoxusPreloadOptions): NoxusPreloadAPI;
|
|
409
|
+
|
|
390
410
|
/**
|
|
391
411
|
* Logger is a utility class for logging messages to the console.
|
|
392
412
|
*/
|
|
@@ -462,4 +482,4 @@ declare namespace Logger {
|
|
|
462
482
|
};
|
|
463
483
|
}
|
|
464
484
|
|
|
465
|
-
export { BadGatewayException, BadRequestException, CONTROLLER_METADATA_KEY, ConflictException, Controller, type ControllerAction, ForbiddenException, GatewayTimeoutException, HttpVersionNotSupportedException, type IApp, type IControllerMetadata, IGuard, type IMiddleware, type IModuleMetadata, INJECTABLE_METADATA_KEY, IResponse, type IRouteDefinition, Injectable, InsufficientStorageException, InternalServerException, Lifetime, type LogLevel, Logger, LoopDetectedException, MODULE_METADATA_KEY, MaybeAsync, MethodNotAllowedException, Module, NetworkAuthenticationRequiredException, NetworkConnectTimeoutException, type NextFunction, NotAcceptableException, NotExtendedException, NotFoundException, NotImplementedException, NoxApp, NoxSocket, PaymentRequiredException, Request, RequestTimeoutException, ResponseException, Router, ServiceUnavailableException, TooManyRequestsException, Type, UnauthorizedException, UpgradeRequiredException, UseMiddlewares, VariantAlsoNegotiatesException, bootstrapApplication, getControllerMetadata, getInjectableMetadata, getMiddlewaresForController, getMiddlewaresForControllerAction, getModuleMetadata };
|
|
485
|
+
export { BadGatewayException, BadRequestException, CONTROLLER_METADATA_KEY, ConflictException, Controller, type ControllerAction, ForbiddenException, GatewayTimeoutException, HttpVersionNotSupportedException, type IApp, type IControllerMetadata, IGuard, type IMiddleware, type IModuleMetadata, INJECTABLE_METADATA_KEY, IPortRequester, IResponse, type IRouteDefinition, Injectable, InsufficientStorageException, InternalServerException, Lifetime, type LogLevel, Logger, LoopDetectedException, MODULE_METADATA_KEY, MaybeAsync, MethodNotAllowedException, Module, NetworkAuthenticationRequiredException, NetworkConnectTimeoutException, type NextFunction, NotAcceptableException, NotExtendedException, NotFoundException, NotImplementedException, NoxApp, NoxSocket, type NoxusPreloadAPI, type NoxusPreloadOptions, PaymentRequiredException, Request, RequestTimeoutException, ResponseException, Router, ServiceUnavailableException, TooManyRequestsException, Type, UnauthorizedException, UpgradeRequiredException, UseMiddlewares, VariantAlsoNegotiatesException, bootstrapApplication, exposeNoxusBridge, getControllerMetadata, getInjectableMetadata, getMiddlewaresForController, getMiddlewaresForControllerAction, getModuleMetadata, hasInjectableMetadata };
|