@noxfly/noxus 3.0.0-dev.2 → 3.0.0-dev.4

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.
@@ -112,10 +112,11 @@ declare class Request {
112
112
  readonly id: string;
113
113
  readonly method: HttpMethod;
114
114
  readonly path: string;
115
- readonly body: any;
115
+ readonly body: unknown;
116
116
  readonly context: AppInjector;
117
117
  readonly params: Record<string, string>;
118
- constructor(event: Electron.MessageEvent, senderId: number, id: string, method: HttpMethod, path: string, body: any);
118
+ readonly query: Record<string, string>;
119
+ constructor(event: Electron.MessageEvent, senderId: number, id: string, method: HttpMethod, path: string, body: unknown, query?: Record<string, string>);
119
120
  }
120
121
  /**
121
122
  * The IRequest interface defines the structure of a request object.
@@ -128,12 +129,14 @@ interface IRequest<TBody = unknown> {
128
129
  path: string;
129
130
  method: HttpMethod;
130
131
  body?: TBody;
132
+ query?: Record<string, string>;
131
133
  }
132
134
  interface IBatchRequestItem<TBody = unknown> {
133
135
  requestId?: string;
134
136
  path: string;
135
137
  method: AtomicHttpMethod;
136
138
  body?: TBody;
139
+ query?: Record<string, string>;
137
140
  }
138
141
  interface IBatchRequestPayload {
139
142
  requests: IBatchRequestItem[];
@@ -208,12 +211,22 @@ interface RendererClientOptions {
208
211
  initMessageType?: string;
209
212
  windowRef?: Window;
210
213
  generateRequestId?: () => string;
214
+ /**
215
+ * Timeout in milliseconds for IPC requests.
216
+ * If the main process does not respond within this duration,
217
+ * the request Promise is rejected and the pending entry cleaned up.
218
+ * Defaults to 10 000 ms. Set to 0 to disable.
219
+ */
220
+ requestTimeout?: number;
221
+ /** @default true */
222
+ enableLogging?: boolean;
211
223
  }
212
224
  interface PendingRequest<T = unknown> {
213
225
  resolve: (value: T) => void;
214
226
  reject: (reason: IResponse<T>) => void;
215
227
  request: IRequest;
216
228
  submittedAt: number;
229
+ timer?: ReturnType<typeof setTimeout>;
217
230
  }
218
231
  declare class NoxRendererClient {
219
232
  readonly events: RendererEventRegistry;
@@ -225,10 +238,12 @@ declare class NoxRendererClient {
225
238
  private readonly initMessageType;
226
239
  private readonly windowRef;
227
240
  private readonly generateRequestId;
241
+ private readonly requestTimeout;
228
242
  private isReady;
229
243
  private setupPromise;
230
244
  private setupResolve;
231
245
  private setupReject;
246
+ private enableLogging;
232
247
  constructor(options?: RendererClientOptions);
233
248
  setup(): Promise<void>;
234
249
  dispose(): void;
@@ -112,10 +112,11 @@ declare class Request {
112
112
  readonly id: string;
113
113
  readonly method: HttpMethod;
114
114
  readonly path: string;
115
- readonly body: any;
115
+ readonly body: unknown;
116
116
  readonly context: AppInjector;
117
117
  readonly params: Record<string, string>;
118
- constructor(event: Electron.MessageEvent, senderId: number, id: string, method: HttpMethod, path: string, body: any);
118
+ readonly query: Record<string, string>;
119
+ constructor(event: Electron.MessageEvent, senderId: number, id: string, method: HttpMethod, path: string, body: unknown, query?: Record<string, string>);
119
120
  }
120
121
  /**
121
122
  * The IRequest interface defines the structure of a request object.
@@ -128,12 +129,14 @@ interface IRequest<TBody = unknown> {
128
129
  path: string;
129
130
  method: HttpMethod;
130
131
  body?: TBody;
132
+ query?: Record<string, string>;
131
133
  }
132
134
  interface IBatchRequestItem<TBody = unknown> {
133
135
  requestId?: string;
134
136
  path: string;
135
137
  method: AtomicHttpMethod;
136
138
  body?: TBody;
139
+ query?: Record<string, string>;
137
140
  }
138
141
  interface IBatchRequestPayload {
139
142
  requests: IBatchRequestItem[];
@@ -208,12 +211,22 @@ interface RendererClientOptions {
208
211
  initMessageType?: string;
209
212
  windowRef?: Window;
210
213
  generateRequestId?: () => string;
214
+ /**
215
+ * Timeout in milliseconds for IPC requests.
216
+ * If the main process does not respond within this duration,
217
+ * the request Promise is rejected and the pending entry cleaned up.
218
+ * Defaults to 10 000 ms. Set to 0 to disable.
219
+ */
220
+ requestTimeout?: number;
221
+ /** @default true */
222
+ enableLogging?: boolean;
211
223
  }
212
224
  interface PendingRequest<T = unknown> {
213
225
  resolve: (value: T) => void;
214
226
  reject: (reason: IResponse<T>) => void;
215
227
  request: IRequest;
216
228
  submittedAt: number;
229
+ timer?: ReturnType<typeof setTimeout>;
217
230
  }
218
231
  declare class NoxRendererClient {
219
232
  readonly events: RendererEventRegistry;
@@ -225,10 +238,12 @@ declare class NoxRendererClient {
225
238
  private readonly initMessageType;
226
239
  private readonly windowRef;
227
240
  private readonly generateRequestId;
241
+ private readonly requestTimeout;
228
242
  private isReady;
229
243
  private setupPromise;
230
244
  private setupResolve;
231
245
  private setupReject;
246
+ private enableLogging;
232
247
  constructor(options?: RendererClientOptions);
233
248
  setup(): Promise<void>;
234
249
  dispose(): void;
package/dist/renderer.js CHANGED
@@ -9,6 +9,9 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
9
9
  var __getOwnPropNames = Object.getOwnPropertyNames;
10
10
  var __hasOwnProp = Object.prototype.hasOwnProperty;
11
11
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
12
+ var __esm = (fn, res) => function __init() {
13
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
14
+ };
12
15
  var __export = (target, all) => {
13
16
  for (var name in all)
14
17
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -23,141 +26,161 @@ var __copyProps = (to, from, except, desc) => {
23
26
  };
24
27
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
25
28
 
26
- // src/renderer.ts
27
- var renderer_exports = {};
28
- __export(renderer_exports, {
29
- NoxRendererClient: () => NoxRendererClient,
30
- RENDERER_EVENT_TYPE: () => RENDERER_EVENT_TYPE,
31
- RendererEventRegistry: () => RendererEventRegistry,
32
- Request: () => Request,
33
- createRendererEventMessage: () => createRendererEventMessage,
34
- isRendererEventMessage: () => isRendererEventMessage
35
- });
36
- module.exports = __toCommonJS(renderer_exports);
37
-
38
29
  // src/utils/forward-ref.ts
39
- var _ForwardReference = class _ForwardReference {
40
- constructor(forwardRefFn) {
41
- this.forwardRefFn = forwardRefFn;
30
+ var _ForwardReference, ForwardReference;
31
+ var init_forward_ref = __esm({
32
+ "src/utils/forward-ref.ts"() {
33
+ "use strict";
34
+ _ForwardReference = class _ForwardReference {
35
+ constructor(forwardRefFn) {
36
+ this.forwardRefFn = forwardRefFn;
37
+ }
38
+ };
39
+ __name(_ForwardReference, "ForwardReference");
40
+ ForwardReference = _ForwardReference;
42
41
  }
43
- };
44
- __name(_ForwardReference, "ForwardReference");
45
- var ForwardReference = _ForwardReference;
42
+ });
46
43
 
47
44
  // src/DI/token.ts
48
- var _Token = class _Token {
49
- constructor(target) {
50
- this.target = target;
51
- this.description = typeof target === "string" ? target : target.name;
52
- }
53
- toString() {
54
- return `Token(${this.description})`;
45
+ var _Token, Token;
46
+ var init_token = __esm({
47
+ "src/DI/token.ts"() {
48
+ "use strict";
49
+ _Token = class _Token {
50
+ constructor(target) {
51
+ this.target = target;
52
+ this.description = typeof target === "string" ? target : target.name;
53
+ }
54
+ toString() {
55
+ return `Token(${this.description})`;
56
+ }
57
+ };
58
+ __name(_Token, "Token");
59
+ Token = _Token;
55
60
  }
56
- };
57
- __name(_Token, "Token");
58
- var Token = _Token;
61
+ });
59
62
 
60
63
  // src/DI/app-injector.ts
61
64
  function keyOf(k) {
62
65
  return k;
63
66
  }
64
- __name(keyOf, "keyOf");
65
- var _AppInjector = class _AppInjector {
66
- constructor(name = null) {
67
- this.name = name;
68
- this.bindings = /* @__PURE__ */ new Map();
69
- this.singletons = /* @__PURE__ */ new Map();
70
- this.scoped = /* @__PURE__ */ new Map();
71
- }
72
- /**
73
- * Creates a child scope for per-request lifetime resolution.
74
- */
75
- createScope() {
76
- const scope = new _AppInjector();
77
- scope.bindings = this.bindings;
78
- scope.singletons = this.singletons;
79
- return scope;
80
- }
81
- /**
82
- * Registers a binding explicitly.
83
- */
84
- register(key, implementation, lifetime, deps = []) {
85
- const k = keyOf(key);
86
- if (!this.bindings.has(k)) {
87
- this.bindings.set(k, { lifetime, implementation, deps });
88
- }
89
- }
90
- /**
91
- * Resolves a dependency by token or class reference.
92
- */
93
- resolve(target) {
94
- if (target instanceof ForwardReference) {
95
- return this._resolveForwardRef(target);
96
- }
97
- const k = keyOf(target);
98
- if (this.singletons.has(k)) {
99
- return this.singletons.get(k);
100
- }
101
- const binding = this.bindings.get(k);
102
- if (!binding) {
103
- const name = target instanceof Token ? target.description : target.name ?? "unknown";
104
- throw new Error(
105
- `[Noxus DI] No binding found for "${name}".
106
- Did you forget to declare it in @Injectable({ deps }) or in bootstrapApplication({ singletons })?`
107
- );
108
- }
109
- switch (binding.lifetime) {
110
- case "transient":
111
- return this._instantiate(binding);
112
- case "scope": {
113
- if (this.scoped.has(k)) return this.scoped.get(k);
114
- const inst = this._instantiate(binding);
115
- this.scoped.set(k, inst);
116
- return inst;
67
+ var _AppInjector, AppInjector, RootInjector;
68
+ var init_app_injector = __esm({
69
+ "src/DI/app-injector.ts"() {
70
+ "use strict";
71
+ init_forward_ref();
72
+ init_token();
73
+ __name(keyOf, "keyOf");
74
+ _AppInjector = class _AppInjector {
75
+ constructor(name = null) {
76
+ this.name = name;
77
+ this.bindings = /* @__PURE__ */ new Map();
78
+ this.singletons = /* @__PURE__ */ new Map();
79
+ this.scoped = /* @__PURE__ */ new Map();
80
+ }
81
+ /**
82
+ * Creates a child scope for per-request lifetime resolution.
83
+ */
84
+ createScope() {
85
+ const scope = new _AppInjector();
86
+ scope.bindings = this.bindings;
87
+ scope.singletons = this.singletons;
88
+ return scope;
117
89
  }
118
- case "singleton": {
119
- if (this.singletons.has(k)) return this.singletons.get(k);
120
- const inst = this._instantiate(binding);
121
- this.singletons.set(k, inst);
122
- if (binding.instance === void 0) {
123
- binding.instance = inst;
90
+ /**
91
+ * Registers a binding explicitly.
92
+ */
93
+ register(key, implementation, lifetime, deps = []) {
94
+ const k = keyOf(key);
95
+ if (!this.bindings.has(k)) {
96
+ this.bindings.set(k, { lifetime, implementation, deps });
124
97
  }
125
- return inst;
126
98
  }
127
- }
128
- }
129
- // -------------------------------------------------------------------------
130
- _resolveForwardRef(ref) {
131
- return new Proxy({}, {
132
- get: /* @__PURE__ */ __name((_obj, prop, receiver) => {
133
- const realType = ref.forwardRefFn();
134
- const instance = this.resolve(realType);
135
- const value = Reflect.get(instance, prop, receiver);
136
- return typeof value === "function" ? value.bind(instance) : value;
137
- }, "get"),
138
- set: /* @__PURE__ */ __name((_obj, prop, value, receiver) => {
139
- const realType = ref.forwardRefFn();
140
- const instance = this.resolve(realType);
141
- return Reflect.set(instance, prop, value, receiver);
142
- }, "set"),
143
- getPrototypeOf: /* @__PURE__ */ __name(() => {
144
- const realType = ref.forwardRefFn();
145
- return realType.prototype;
146
- }, "getPrototypeOf")
147
- });
148
- }
149
- _instantiate(binding) {
150
- const resolvedDeps = binding.deps.map((dep) => this.resolve(dep));
151
- return new binding.implementation(...resolvedDeps);
99
+ /**
100
+ * Resolves a dependency by token or class reference.
101
+ */
102
+ resolve(target) {
103
+ if (target instanceof ForwardReference) {
104
+ return this._resolveForwardRef(target);
105
+ }
106
+ const k = keyOf(target);
107
+ if (this.singletons.has(k)) {
108
+ return this.singletons.get(k);
109
+ }
110
+ const binding = this.bindings.get(k);
111
+ if (!binding) {
112
+ const name = target instanceof Token ? target.description : target.name ?? "unknown";
113
+ throw new Error(
114
+ `[Noxus DI] No binding found for "${name}".
115
+ Did you forget to declare it in @Injectable({ deps }) or in bootstrapApplication({ singletons })?`
116
+ );
117
+ }
118
+ switch (binding.lifetime) {
119
+ case "transient":
120
+ return this._instantiate(binding);
121
+ case "scope": {
122
+ if (this.scoped.has(k)) return this.scoped.get(k);
123
+ const inst = this._instantiate(binding);
124
+ this.scoped.set(k, inst);
125
+ return inst;
126
+ }
127
+ case "singleton": {
128
+ if (this.singletons.has(k)) return this.singletons.get(k);
129
+ const inst = this._instantiate(binding);
130
+ this.singletons.set(k, inst);
131
+ if (binding.instance === void 0) {
132
+ binding.instance = inst;
133
+ }
134
+ return inst;
135
+ }
136
+ }
137
+ }
138
+ // -------------------------------------------------------------------------
139
+ _resolveForwardRef(ref) {
140
+ let resolved;
141
+ return new Proxy({}, {
142
+ get: /* @__PURE__ */ __name((_obj, prop, receiver) => {
143
+ resolved ?? (resolved = this.resolve(ref.forwardRefFn()));
144
+ const value = Reflect.get(resolved, prop, receiver);
145
+ return typeof value === "function" ? value.bind(resolved) : value;
146
+ }, "get"),
147
+ set: /* @__PURE__ */ __name((_obj, prop, value, receiver) => {
148
+ resolved ?? (resolved = this.resolve(ref.forwardRefFn()));
149
+ return Reflect.set(resolved, prop, value, receiver);
150
+ }, "set"),
151
+ getPrototypeOf: /* @__PURE__ */ __name(() => {
152
+ resolved ?? (resolved = this.resolve(ref.forwardRefFn()));
153
+ return Object.getPrototypeOf(resolved);
154
+ }, "getPrototypeOf")
155
+ });
156
+ }
157
+ _instantiate(binding) {
158
+ const resolvedDeps = binding.deps.map((dep) => this.resolve(dep));
159
+ return new binding.implementation(...resolvedDeps);
160
+ }
161
+ };
162
+ __name(_AppInjector, "AppInjector");
163
+ AppInjector = _AppInjector;
164
+ RootInjector = new AppInjector("root");
152
165
  }
153
- };
154
- __name(_AppInjector, "AppInjector");
155
- var AppInjector = _AppInjector;
156
- var RootInjector = new AppInjector("root");
166
+ });
167
+
168
+ // src/renderer.ts
169
+ var renderer_exports = {};
170
+ __export(renderer_exports, {
171
+ NoxRendererClient: () => NoxRendererClient,
172
+ RENDERER_EVENT_TYPE: () => RENDERER_EVENT_TYPE,
173
+ RendererEventRegistry: () => RendererEventRegistry,
174
+ Request: () => Request,
175
+ createRendererEventMessage: () => createRendererEventMessage,
176
+ isRendererEventMessage: () => isRendererEventMessage
177
+ });
178
+ module.exports = __toCommonJS(renderer_exports);
157
179
 
158
180
  // src/internal/request.ts
181
+ init_app_injector();
159
182
  var _Request = class _Request {
160
- constructor(event, senderId, id, method, path, body) {
183
+ constructor(event, senderId, id, method, path, body, query) {
161
184
  this.event = event;
162
185
  this.senderId = senderId;
163
186
  this.id = id;
@@ -167,6 +190,7 @@ var _Request = class _Request {
167
190
  this.context = RootInjector.createScope();
168
191
  this.params = {};
169
192
  this.path = path.replace(/^\/|\/$/g, "");
193
+ this.query = query ?? {};
170
194
  }
171
195
  };
172
196
  __name(_Request, "Request");
@@ -369,6 +393,9 @@ var _NoxRendererClient = class _NoxRendererClient {
369
393
  console.error(`[Noxus] No pending handler found for request ${response.requestId}.`);
370
394
  return;
371
395
  }
396
+ if (pending.timer !== void 0) {
397
+ clearTimeout(pending.timer);
398
+ }
372
399
  this.pendingRequests.delete(response.requestId);
373
400
  this.onRequestCompleted(pending, response);
374
401
  if (response.status >= 400) {
@@ -382,6 +409,8 @@ var _NoxRendererClient = class _NoxRendererClient {
382
409
  this.bridge = resolvedBridge ?? null;
383
410
  this.initMessageType = options.initMessageType ?? DEFAULT_INIT_EVENT;
384
411
  this.generateRequestId = options.generateRequestId ?? defaultRequestId;
412
+ this.requestTimeout = options.requestTimeout ?? 1e4;
413
+ this.enableLogging = options.enableLogging ?? true;
385
414
  }
386
415
  async setup() {
387
416
  if (this.isReady) {
@@ -409,6 +438,11 @@ var _NoxRendererClient = class _NoxRendererClient {
409
438
  this.socketPort = void 0;
410
439
  this.senderId = void 0;
411
440
  this.isReady = false;
441
+ for (const pending of this.pendingRequests.values()) {
442
+ if (pending.timer !== void 0) {
443
+ clearTimeout(pending.timer);
444
+ }
445
+ }
412
446
  this.pendingRequests.clear();
413
447
  }
414
448
  async request(request) {
@@ -433,6 +467,12 @@ var _NoxRendererClient = class _NoxRendererClient {
433
467
  request: message,
434
468
  submittedAt: Date.now()
435
469
  };
470
+ if (this.requestTimeout > 0) {
471
+ pending.timer = setTimeout(() => {
472
+ this.pendingRequests.delete(message.requestId);
473
+ reject(this.createErrorResponse(message.requestId, `Request timed out after ${this.requestTimeout}ms`));
474
+ }, this.requestTimeout);
475
+ }
436
476
  this.pendingRequests.set(message.requestId, pending);
437
477
  this.requestPort.postMessage(message);
438
478
  });
@@ -450,6 +490,9 @@ var _NoxRendererClient = class _NoxRendererClient {
450
490
  return this.senderId;
451
491
  }
452
492
  onRequestCompleted(pending, response) {
493
+ if (!this.enableLogging) {
494
+ return;
495
+ }
453
496
  if (typeof console.groupCollapsed === "function") {
454
497
  console.groupCollapsed(`${response.status} ${pending.request.method} /${pending.request.path}`);
455
498
  }