@noxfly/noxus 3.0.0-dev.0 → 3.0.0-dev.10

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.
Files changed (59) hide show
  1. package/README.md +132 -16
  2. package/dist/child.d.mts +118 -4
  3. package/dist/child.d.ts +118 -4
  4. package/dist/child.js +402 -859
  5. package/dist/child.js.map +1 -0
  6. package/dist/child.mjs +389 -847
  7. package/dist/child.mjs.map +1 -0
  8. package/dist/main.d.mts +517 -25
  9. package/dist/main.d.ts +517 -25
  10. package/dist/main.js +1088 -988
  11. package/dist/main.js.map +1 -0
  12. package/dist/main.mjs +983 -884
  13. package/dist/main.mjs.map +1 -0
  14. package/dist/preload.d.mts +28 -0
  15. package/dist/preload.d.ts +28 -0
  16. package/dist/preload.js +95 -0
  17. package/dist/preload.js.map +1 -0
  18. package/dist/preload.mjs +70 -0
  19. package/dist/preload.mjs.map +1 -0
  20. package/dist/renderer.d.mts +186 -23
  21. package/dist/renderer.d.ts +186 -23
  22. package/dist/renderer.js +170 -170
  23. package/dist/renderer.js.map +1 -0
  24. package/dist/renderer.mjs +159 -157
  25. package/dist/renderer.mjs.map +1 -0
  26. package/package.json +35 -21
  27. package/.editorconfig +0 -16
  28. package/.github/copilot-instructions.md +0 -32
  29. package/.vscode/settings.json +0 -3
  30. package/eslint.config.js +0 -109
  31. package/scripts/postbuild.js +0 -31
  32. package/src/DI/app-injector.ts +0 -151
  33. package/src/DI/injector-explorer.ts +0 -143
  34. package/src/DI/token.ts +0 -53
  35. package/src/app.ts +0 -217
  36. package/src/bootstrap.ts +0 -108
  37. package/src/decorators/controller.decorator.ts +0 -58
  38. package/src/decorators/guards.decorator.ts +0 -15
  39. package/src/decorators/injectable.decorator.ts +0 -81
  40. package/src/decorators/method.decorator.ts +0 -66
  41. package/src/decorators/middleware.decorator.ts +0 -15
  42. package/src/exceptions.ts +0 -57
  43. package/src/index.ts +0 -13
  44. package/src/main.ts +0 -26
  45. package/src/non-electron-process.ts +0 -22
  46. package/src/preload-bridge.ts +0 -75
  47. package/src/renderer-client.ts +0 -338
  48. package/src/renderer-events.ts +0 -110
  49. package/src/request.ts +0 -97
  50. package/src/router.ts +0 -353
  51. package/src/routes.ts +0 -78
  52. package/src/socket.ts +0 -73
  53. package/src/utils/forward-ref.ts +0 -31
  54. package/src/utils/logger.ts +0 -430
  55. package/src/utils/radix-tree.ts +0 -210
  56. package/src/utils/types.ts +0 -21
  57. package/src/window/window-manager.ts +0 -255
  58. package/tsconfig.json +0 -29
  59. package/tsup.config.ts +0 -34
@@ -1,430 +0,0 @@
1
- /**
2
- * @copyright 2025 NoxFly
3
- * @license MIT
4
- * @author NoxFly
5
- */
6
-
7
- import * as fs from 'fs';
8
- import * as path from 'path';
9
-
10
- /**
11
- * Logger is a utility class for logging messages to the console.
12
- */
13
- export type LogLevel =
14
- | 'debug'
15
- | 'comment'
16
- | 'log'
17
- | 'info'
18
- | 'warn'
19
- | 'error'
20
- | 'critical'
21
- ;
22
-
23
- interface FileLogState {
24
- queue: string[];
25
- isWriting: boolean;
26
- }
27
-
28
-
29
-
30
- /**
31
- * Returns a formatted timestamp for logging.
32
- */
33
- function getPrettyTimestamp(): string {
34
- const now = new Date();
35
- return `${now.getDate().toString().padStart(2, '0')}/${(now.getMonth() + 1).toString().padStart(2, '0')}/${now.getFullYear()}`
36
- + ` ${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}:${now.getSeconds().toString().padStart(2, '0')}`;
37
- }
38
-
39
- /**
40
- * Generates a log prefix for the console output.
41
- * @param callee - The name of the function or class that is logging the message.
42
- * @param messageType - The type of message being logged (e.g., 'log', 'info', 'warn', 'error', 'debug').
43
- * @param color - The color to use for the log message.
44
- * @returns A formatted string that includes the timestamp, process ID, message type, and callee name.
45
- */
46
- function getLogPrefix(callee: string, messageType: string, color?: string): string {
47
- const timestamp = getPrettyTimestamp();
48
-
49
- const spaces = " ".repeat(10 - messageType.length);
50
-
51
- let colReset = Logger.colors.initial;
52
- let colCallee = Logger.colors.yellow;
53
-
54
- if(color === undefined) {
55
- color = "";
56
- colReset = "";
57
- colCallee = "";
58
- }
59
-
60
- return `${color}[APP] ${process.pid} - ${colReset}`
61
- + `${timestamp}${spaces}`
62
- + `${color}${messageType.toUpperCase()}${colReset} `
63
- + `${colCallee}[${callee}]${colReset}`;
64
- }
65
-
66
- /**
67
- * Formats an object into a string representation for logging.
68
- * It converts the object to JSON and adds indentation for readability.
69
- * @param prefix - The prefix to use for the formatted object.
70
- * @param arg - The object to format.
71
- * @returns A formatted string representation of the object, with each line prefixed by the specified prefix.
72
- */
73
- function formatObject(prefix: string, arg: object, enableColor: boolean = true): string {
74
- const json = JSON.stringify(arg, null, 2);
75
-
76
- let colStart = "";
77
- let colLine = "";
78
- let colReset = "";
79
-
80
- if(enableColor) {
81
- colStart = Logger.colors.darkGrey;
82
- colLine = Logger.colors.grey;
83
- colReset = Logger.colors.initial;
84
- }
85
-
86
- const prefixedJson = json
87
- .split('\n')
88
- .map((line, idx) => idx === 0 ? `${colStart}${line}` : `${prefix} ${colLine}${line}`)
89
- .join('\n') + colReset;
90
-
91
- return prefixedJson;
92
- }
93
-
94
- /**
95
- * Formats the arguments for logging.
96
- * It colors strings and formats objects with indentation.
97
- * This function is used to prepare the arguments for console output.
98
- * @param prefix - The prefix to use for the formatted arguments.
99
- * @param args - The arguments to format.
100
- * @param color - The color to use for the formatted arguments.
101
- * @returns An array of formatted arguments, where strings are colored and objects are formatted with indentation.
102
- */
103
- function formattedArgs(prefix: string, args: any[], color?: string): any[] {
104
- let colReset = Logger.colors.initial;
105
-
106
- if(color === undefined) {
107
- color = "";
108
- colReset = "";
109
- }
110
-
111
- return args.map(arg => {
112
- if(typeof arg === "string") {
113
- return `${color}${arg}${colReset}`;
114
- }
115
-
116
- else if(typeof arg === "object") {
117
- return formatObject(prefix, arg, color !== "");
118
- }
119
-
120
- return arg;
121
- });
122
- }
123
-
124
- /**
125
- * Gets the name of the caller function or class from the stack trace.
126
- * This function is used to determine the context of the log message.
127
- * @returns The name of the caller function or class.
128
- */
129
- function getCallee(): string {
130
- const stack = new Error().stack?.split('\n') ?? [];
131
- const caller = stack[3]
132
- ?.trim()
133
- .match(/at (.+?)(?:\..+)? .+$/)
134
- ?.[1]
135
- ?.replace("Object", "")
136
- .replace(/^_/, "")
137
- || "App";
138
- return caller;
139
- }
140
-
141
- /**
142
- * Checks if the current log level allows logging the specified level.
143
- * This function compares the current log level with the specified level to determine if logging should occur.
144
- * @param level - The log level to check.
145
- * @returns A boolean indicating whether the log level is enabled.
146
- */
147
- function canLog(level: LogLevel): boolean {
148
- return logLevels.has(level);
149
- }
150
-
151
- /**
152
- * Writes a log message to a file asynchronously to avoid blocking the event loop.
153
- * It batches messages if writing is already in progress.
154
- * @param filepath - The path to the log file.
155
- */
156
- function processLogQueue(filepath: string): void {
157
- const state = fileStates.get(filepath);
158
-
159
- if(!state || state.isWriting || state.queue.length === 0) {
160
- return;
161
- }
162
-
163
- state.isWriting = true;
164
-
165
- // Optimization: Grab all pending messages to write in one go
166
- const messagesToWrite = state.queue.join('\n') + '\n';
167
- state.queue = []; // Clear the queue immediately
168
-
169
- const dir = path.dirname(filepath);
170
-
171
- // Using async IO to allow other operations
172
- fs.mkdir(dir, { recursive: true }, (err) => {
173
- if(err) {
174
- console.error(`[Logger] Failed to create directory ${dir}`, err);
175
- state.isWriting = false;
176
- return;
177
- }
178
-
179
- fs.appendFile(filepath, messagesToWrite, { encoding: "utf-8" }, (err) => {
180
- state.isWriting = false;
181
-
182
- if(err) {
183
- console.error(`[Logger] Failed to write log to ${filepath}`, err);
184
- }
185
-
186
- // If new messages arrived while we were writing, process them now
187
- if(state.queue.length > 0) {
188
- processLogQueue(filepath);
189
- }
190
- });
191
- });
192
- }
193
-
194
- /**
195
- * Adds a message to the file queue and triggers processing.
196
- */
197
- function enqueue(filepath: string, message: string): void {
198
- if(!fileStates.has(filepath)) {
199
- fileStates.set(filepath, { queue: [], isWriting: false });
200
- }
201
-
202
- const state = fileStates.get(filepath)!;
203
- state.queue.push(message);
204
-
205
- processLogQueue(filepath);
206
- }
207
-
208
- /**
209
- *
210
- */
211
- function output(level: LogLevel, args: any[]): void {
212
- if(!canLog(level)) {
213
- return;
214
- }
215
-
216
- const callee = getCallee();
217
-
218
- {
219
- const prefix = getLogPrefix(callee, level, logLevelColors[level]);
220
- const data = formattedArgs(prefix, args, logLevelColors[level]);
221
-
222
- logLevelChannel[level](prefix, ...data);
223
- }
224
-
225
- {
226
- const prefix = getLogPrefix(callee, level);
227
- const data = formattedArgs(prefix, args);
228
-
229
- const filepath = fileSettings.get(level)?.filepath;
230
-
231
- if(filepath) {
232
- const message = prefix + " " + data.join(" ").replace(/\x1b\[[0-9;]*m/g, ''); // Remove ANSI codes
233
- enqueue(filepath, message);
234
- }
235
- }
236
- }
237
-
238
-
239
-
240
- export namespace Logger {
241
-
242
- /**
243
- * Sets the log level for the logger.
244
- * This function allows you to change the log level dynamically at runtime.
245
- * This won't affect the startup logs.
246
- *
247
- * If the parameter is a single LogLevel, all log levels with equal or higher severity will be enabled.
248
-
249
- * If the parameter is an array of LogLevels, only the specified levels will be enabled.
250
- *
251
- * @param level Sets the log level for the logger.
252
- */
253
- export function setLogLevel(level: LogLevel | LogLevel[]): void {
254
- logLevels.clear();
255
-
256
- if(Array.isArray(level)) {
257
- for(const lvl of level) {
258
- logLevels.add(lvl);
259
- }
260
- }
261
- else {
262
- const targetRank = logLevelRank[level];
263
-
264
- for(const [lvl, rank] of Object.entries(logLevelRank) as [LogLevel, number][]) {
265
- if(rank >= targetRank) {
266
- logLevels.add(lvl);
267
- }
268
- }
269
- }
270
- }
271
-
272
- /**
273
- * Logs a message to the console with log level LOG.
274
- * This function formats the message with a timestamp, process ID, and the name of the caller function or class.
275
- * It uses different colors for different log levels to enhance readability.
276
- * @param args The arguments to log.
277
- */
278
- export function log(...args: any[]): void {
279
- output("log", args);
280
- }
281
-
282
- /**
283
- * Logs a message to the console with log level INFO.
284
- * This function formats the message with a timestamp, process ID, and the name of the caller function or class.
285
- * It uses different colors for different log levels to enhance readability.
286
- * @param args The arguments to log.
287
- */
288
- export function info(...args: any[]): void {
289
- output("info", args);
290
- }
291
-
292
- /**
293
- * Logs a message to the console with log level WARN.
294
- * This function formats the message with a timestamp, process ID, and the name of the caller function or class.
295
- * It uses different colors for different log levels to enhance readability.
296
- * @param args The arguments to log.
297
- */
298
- export function warn(...args: any[]): void {
299
- output("warn", args);
300
- }
301
-
302
- /**
303
- * Logs a message to the console with log level ERROR.
304
- * This function formats the message with a timestamp, process ID, and the name of the caller function or class.
305
- * It uses different colors for different log levels to enhance readability.
306
- * @param args The arguments to log.
307
- */
308
- export function error(...args: any[]): void {
309
- output("error", args);
310
- }
311
-
312
- /**
313
- * Logs a message to the console with log level ERROR and a grey color scheme.
314
- */
315
- export function errorStack(...args: any[]): void {
316
- output("error", args);
317
- }
318
-
319
- /**
320
- * Logs a message to the console with log level DEBUG.
321
- * This function formats the message with a timestamp, process ID, and the name of the caller function or class.
322
- * It uses different colors for different log levels to enhance readability.
323
- * @param args The arguments to log.
324
- */
325
- export function debug(...args: any[]): void {
326
- output("debug", args);
327
- }
328
-
329
- /**
330
- * Logs a message to the console with log level COMMENT.
331
- * This function formats the message with a timestamp, process ID, and the name of the caller function or class.
332
- * It uses different colors for different log levels to enhance readability.
333
- * @param args The arguments to log.
334
- */
335
- export function comment(...args: any[]): void {
336
- output("comment", args);
337
- }
338
-
339
- /**
340
- * Logs a message to the console with log level CRITICAL.
341
- * This function formats the message with a timestamp, process ID, and the name of the caller function or class.
342
- * It uses different colors for different log levels to enhance readability.
343
- * @param args The arguments to log.
344
- */
345
- export function critical(...args: any[]): void {
346
- output("critical", args);
347
- }
348
-
349
- /**
350
- * Enables logging to a file output for the specified log levels.
351
- * @param filepath The path to the log file.
352
- * @param levels The log levels to enable file logging for. Defaults to all levels.
353
- */
354
- export function enableFileLogging(filepath: string, levels: LogLevel[] = ["debug", "comment", "log", "info", "warn", "error", "critical"]): void {
355
- for(const level of levels) {
356
- fileSettings.set(level, { filepath });
357
- }
358
- }
359
-
360
- /**
361
- * Disables logging to a file output for the specified log levels.
362
- * @param levels The log levels to disable file logging for. Defaults to all levels.
363
- */
364
- export function disableFileLogging(levels: LogLevel[] = ["debug", "comment", "log", "info", "warn", "error", "critical"]): void {
365
- for(const level of levels) {
366
- fileSettings.delete(level);
367
- }
368
- }
369
-
370
-
371
- export const colors = {
372
- black: "\x1b[0;30m",
373
- grey: "\x1b[0;37m",
374
- red: "\x1b[0;31m",
375
- green: "\x1b[0;32m",
376
- brown: "\x1b[0;33m",
377
- blue: "\x1b[0;34m",
378
- purple: "\x1b[0;35m",
379
-
380
- darkGrey: "\x1b[1;30m",
381
- lightRed: "\x1b[1;31m",
382
- lightGreen: "\x1b[1;32m",
383
- yellow: "\x1b[1;33m",
384
- lightBlue: "\x1b[1;34m",
385
- magenta: "\x1b[1;35m",
386
- cyan: "\x1b[1;36m",
387
- white: "\x1b[1;37m",
388
-
389
- initial: "\x1b[0m"
390
- };
391
- }
392
-
393
-
394
- const fileSettings: Map<LogLevel, { filepath: string }> = new Map();
395
- const fileStates: Map<string, FileLogState> = new Map(); // filepath -> state
396
-
397
- const logLevels: Set<LogLevel> = new Set();
398
-
399
- const logLevelRank: Record<LogLevel, number> = {
400
- debug: 0,
401
- comment: 1,
402
- log: 2,
403
- info: 3,
404
- warn: 4,
405
- error: 5,
406
- critical: 6,
407
- };
408
-
409
- const logLevelColors: Record<LogLevel, string> = {
410
- debug: Logger.colors.purple,
411
- comment: Logger.colors.grey,
412
- log: Logger.colors.green,
413
- info: Logger.colors.blue,
414
- warn: Logger.colors.brown,
415
- error: Logger.colors.red,
416
- critical: Logger.colors.lightRed,
417
- };
418
-
419
- const logLevelChannel: Record<LogLevel, (message?: any, ...optionalParams: any[]) => void> = {
420
- debug: console.debug,
421
- comment: console.debug,
422
- log: console.log,
423
- info: console.info,
424
- warn: console.warn,
425
- error: console.error,
426
- critical: console.error,
427
- };
428
-
429
-
430
- Logger.setLogLevel("debug");
@@ -1,210 +0,0 @@
1
- /**
2
- * @copyright 2025 NoxFly
3
- * @license MIT
4
- * @author NoxFly
5
- */
6
-
7
- /**
8
- *
9
- */
10
- type Params = Record<string, string>;
11
-
12
- /**
13
- * Represents a search result in the Radix Tree.
14
- */
15
- interface ISearchResult<T> {
16
- node: RadixNode<T>;
17
- params: Params;
18
- }
19
-
20
- /**
21
- * Represents a node in the Radix Tree.
22
- * The represents a path segment
23
- */
24
- class RadixNode<T> {
25
- public segment: string;
26
- public children: RadixNode<T>[] = [];
27
- public value?: T;
28
- public isParam: boolean;
29
- public paramName?: string;
30
-
31
- /**
32
- * Creates a new RadixNode.
33
- * @param segment - The segment of the path this node represents.
34
- */
35
- constructor(segment: string) {
36
- this.segment = segment;
37
- this.isParam = segment.startsWith(":");
38
-
39
- if(this.isParam) {
40
- this.paramName = segment.slice(1);
41
- }
42
- }
43
-
44
- /**
45
- * Matches a child node against a given segment.
46
- * This method checks if the segment matches any of the children nodes.
47
- * @param segment - The segment to match against the children of this node.
48
- * @returns A child node that matches the segment, or undefined if no match is found.
49
- */
50
- public matchChild(segment: string): RadixNode<T> | undefined {
51
- for(const child of this.children) {
52
- if(child.isParam || segment.startsWith(child.segment))
53
- return child; // param match
54
- }
55
-
56
- return undefined;
57
- }
58
-
59
- /**
60
- * Finds a child node that matches the segment exactly.
61
- * This method checks if there is a child node that matches the segment exactly.
62
- * @param segment - The segment to find an exact match for among the children of this node.
63
- * @returns A child node that matches the segment exactly, or undefined if no match is found.
64
- */
65
- public findExactChild(segment: string): RadixNode<T> | undefined {
66
- return this.children.find(c => c.segment === segment);
67
- }
68
-
69
- /**
70
- * Adds a child node to this node's children.
71
- * This method adds a new child node to the list of children for this node.
72
- * @param node - The child node to add to this node's children.
73
- */
74
- public addChild(node: RadixNode<T>): void {
75
- this.children.push(node);
76
- }
77
- }
78
-
79
- /**
80
- *
81
- */
82
- export class RadixTree<T> {
83
- private readonly root = new RadixNode<T>("");
84
-
85
- /**
86
- * Inserts a path and its associated value into the Radix Tree.
87
- * This method normalizes the path and inserts it into the tree, associating it with
88
- * @param path - The path to insert into the tree.
89
- * @param value - The value to associate with the path.
90
- */
91
- public insert(path: string, value: T): void {
92
- const segments = this.normalize(path);
93
- this.insertRecursive(this.root, segments, value);
94
- }
95
-
96
- /**
97
- * Recursively inserts a path into the Radix Tree.
98
- * This method traverses the tree and inserts the segments of the path, creating new nodes
99
- * @param node - The node to start inserting from.
100
- * @param segments - The segments of the path to insert.
101
- * @param value - The value to associate with the path.
102
- */
103
- private insertRecursive(node: RadixNode<T>, segments: string[], value: T): void {
104
- if(segments.length === 0) {
105
- node.value = value;
106
- return;
107
- }
108
-
109
- const segment = segments[0] ?? "";
110
-
111
- let child = node.children.find(c =>
112
- c.isParam === segment.startsWith(":") &&
113
- (c.isParam || c.segment === segment)
114
- );
115
-
116
- if(!child) {
117
- child = new RadixNode<T>(segment);
118
- node.addChild(child);
119
- }
120
-
121
- this.insertRecursive(child, segments.slice(1), value);
122
- }
123
-
124
- /**
125
- * Searches for a path in the Radix Tree.
126
- * This method normalizes the path and searches for it in the tree, returning the node
127
- * @param path - The path to search for in the Radix Tree.
128
- * @returns An ISearchResult containing the node and parameters if a match is found, otherwise undefined.
129
- */
130
- public search(path: string): ISearchResult<T> | undefined {
131
- const segments = this.normalize(path);
132
- return this.searchRecursive(this.root, segments, {});
133
- }
134
-
135
- /**
136
- * Recursively searches for a path in the Radix Tree.
137
- * This method traverses the tree and searches for the segments of the path, collecting parameters
138
- * @param node - The node to start searching from.
139
- * @param segments - The segments of the path to search for.
140
- * @param params - The parameters collected during the search.
141
- * @returns An ISearchResult containing the node and parameters if a match is found, otherwise undefined.
142
- */
143
- private searchRecursive(node: RadixNode<T>, segments: string[], params: Params): ISearchResult<T> | undefined {
144
- if(segments.length === 0) {
145
- if(node.value !== undefined) {
146
- return {
147
- node: node,
148
- params
149
- };
150
- }
151
-
152
- return undefined;
153
- }
154
-
155
- const [segment, ...rest] = segments;
156
-
157
- for(const child of node.children) {
158
- if(child.isParam) {
159
- const paramName = child.paramName!;
160
-
161
- const childParams: Params = {
162
- ...params,
163
- [paramName]: segment ?? "",
164
- };
165
-
166
- if(rest.length === 0) {
167
- return {
168
- node: child,
169
- params: childParams
170
- };
171
- }
172
-
173
- const result = this.searchRecursive(child, rest, childParams);
174
-
175
- if(result)
176
- return result;
177
- }
178
- else if(segment === child.segment) {
179
- if(rest.length === 0) {
180
- return {
181
- node: child,
182
- params
183
- };
184
- }
185
-
186
- const result = this.searchRecursive(child, rest, params);
187
-
188
- if(result)
189
- return result;
190
- }
191
- }
192
-
193
- return undefined;
194
- }
195
-
196
- /**
197
- * Normalizes a path into an array of segments.
198
- * This method removes leading and trailing slashes, splits the path by slashes, and
199
- * @param path - The path to normalize.
200
- * @returns An array of normalized path segments.
201
- */
202
- private normalize(path: string): string[] {
203
- const segments = path
204
- .replace(/^\/+|\/+$/g, "")
205
- .split("/")
206
- .filter(Boolean);
207
-
208
- return ['', ...segments];
209
- }
210
- }
@@ -1,21 +0,0 @@
1
- /**
2
- * @copyright 2025 NoxFly
3
- * @license MIT
4
- * @author NoxFly
5
- */
6
-
7
-
8
- /**
9
- * Represents a generic type that can be either a class or a function.
10
- * This is used to define types that can be instantiated or called.
11
- */
12
- declare const Type: FunctionConstructor;
13
- export interface Type<T> extends Function {
14
- // eslint-disable-next-line @typescript-eslint/prefer-function-type
15
- new (...args: any[]): T;
16
- }
17
-
18
- /**
19
- * Represents a generic type that can be either a value or a promise resolving to that value.
20
- */
21
- export type MaybeAsync<T> = T | Promise<T>;