@riktajs/core 0.7.0 → 0.9.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/README.md +78 -0
- package/dist/core/application.js +16 -3
- package/dist/core/container/abstract-class.utils.d.ts +10 -0
- package/dist/core/container/abstract-class.utils.js +54 -0
- package/dist/core/container/container.d.ts +3 -0
- package/dist/core/container/container.js +78 -7
- package/dist/core/container/implements.decorator.d.ts +6 -0
- package/dist/core/container/implements.decorator.js +45 -0
- package/dist/core/container/index.d.ts +3 -0
- package/dist/core/container/index.js +3 -0
- package/dist/core/container/request-scope.d.ts +16 -0
- package/dist/core/container/request-scope.js +53 -0
- package/dist/core/decorators/autowired.decorator.d.ts +2 -1
- package/dist/core/decorators/autowired.decorator.js +3 -1
- package/dist/core/discovery.d.ts +2 -1
- package/dist/core/discovery.js +22 -10
- package/dist/core/exceptions/discovery.exception.d.ts +18 -0
- package/dist/core/exceptions/discovery.exception.js +43 -0
- package/dist/core/exceptions/index.d.ts +1 -0
- package/dist/core/exceptions/index.js +3 -1
- package/dist/core/guards/execution-context.d.ts +7 -0
- package/dist/core/guards/execution-context.js +8 -0
- package/dist/core/index.d.ts +2 -0
- package/dist/core/index.js +2 -0
- package/dist/core/interceptors/index.d.ts +2 -0
- package/dist/core/interceptors/index.js +6 -0
- package/dist/core/interceptors/interceptor.interface.d.ts +7 -0
- package/dist/core/interceptors/interceptor.interface.js +2 -0
- package/dist/core/interceptors/use-interceptors.decorator.d.ts +6 -0
- package/dist/core/interceptors/use-interceptors.decorator.js +23 -0
- package/dist/core/lifecycle/event-bus.d.ts +9 -4
- package/dist/core/lifecycle/event-bus.js +57 -7
- package/dist/core/profiler/index.d.ts +2 -0
- package/dist/core/profiler/index.js +8 -0
- package/dist/core/profiler/performance-profiler.d.ts +42 -0
- package/dist/core/profiler/performance-profiler.js +101 -0
- package/dist/core/registry.d.ts +12 -0
- package/dist/core/registry.js +45 -0
- package/dist/core/router/router.d.ts +10 -0
- package/dist/core/router/router.js +85 -8
- package/dist/core/types.d.ts +9 -3
- package/package.json +2 -2
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DiscoveryException = void 0;
|
|
4
|
+
class DiscoveryException extends Error {
|
|
5
|
+
filePath;
|
|
6
|
+
originalError;
|
|
7
|
+
failedImports;
|
|
8
|
+
constructor(filePathOrFailures, originalError) {
|
|
9
|
+
if (typeof filePathOrFailures === 'string') {
|
|
10
|
+
const filePath = filePathOrFailures;
|
|
11
|
+
const error = originalError;
|
|
12
|
+
super(`[Rikta Discovery] Failed to import module: ${filePath}\n` +
|
|
13
|
+
`Reason: ${error.message}`);
|
|
14
|
+
this.filePath = filePath;
|
|
15
|
+
this.originalError = error;
|
|
16
|
+
this.failedImports = [{ filePath, error }];
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
const failures = filePathOrFailures;
|
|
20
|
+
const fileList = failures.map(f => ` - ${f.filePath}: ${f.error.message}`).join('\n');
|
|
21
|
+
super(`[Rikta Discovery] Failed to import ${failures.length} module(s):\n${fileList}`);
|
|
22
|
+
this.filePath = failures[0]?.filePath ?? '';
|
|
23
|
+
this.originalError = failures[0]?.error ?? new Error('Unknown error');
|
|
24
|
+
this.failedImports = failures;
|
|
25
|
+
}
|
|
26
|
+
this.name = 'DiscoveryException';
|
|
27
|
+
Error.captureStackTrace(this, this.constructor);
|
|
28
|
+
}
|
|
29
|
+
getReport() {
|
|
30
|
+
const lines = ['Discovery Failures:', ''];
|
|
31
|
+
for (const { filePath, error } of this.failedImports) {
|
|
32
|
+
lines.push(`📁 ${filePath}`);
|
|
33
|
+
lines.push(` Error: ${error.message}`);
|
|
34
|
+
if (error.stack) {
|
|
35
|
+
const stackLines = error.stack.split('\n').slice(1, 4);
|
|
36
|
+
lines.push(` Stack: ${stackLines.join('\n ')}`);
|
|
37
|
+
}
|
|
38
|
+
lines.push('');
|
|
39
|
+
}
|
|
40
|
+
return lines.join('\n');
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
exports.DiscoveryException = DiscoveryException;
|
|
@@ -4,3 +4,4 @@ export { BadRequestException, UnauthorizedException, ForbiddenException, NotFoun
|
|
|
4
4
|
export { ExceptionFilter, ExceptionContext, ErrorResponse, GlobalExceptionFilter, GlobalExceptionFilterOptions, createExceptionHandler, } from './exception-filter';
|
|
5
5
|
export { Catch, CatchMetadata, CATCH_METADATA, getCatchMetadata } from './catch.decorator';
|
|
6
6
|
export { ConfigProviderAlreadyRegisteredException, ConfigProviderNotFoundException, ConfigProviderInstantiationException, } from './config.exceptions';
|
|
7
|
+
export { DiscoveryException, DiscoveryFailure, DiscoveryOptions, } from './discovery.exception';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ConfigProviderInstantiationException = exports.ConfigProviderNotFoundException = exports.ConfigProviderAlreadyRegisteredException = exports.getCatchMetadata = exports.CATCH_METADATA = exports.Catch = exports.createExceptionHandler = exports.GlobalExceptionFilter = exports.GatewayTimeoutException = exports.ServiceUnavailableException = exports.BadGatewayException = exports.NotImplementedException = exports.InternalServerErrorException = exports.TooManyRequestsException = exports.UnprocessableEntityException = exports.UnsupportedMediaTypeException = exports.PayloadTooLargeException = exports.GoneException = exports.ConflictException = exports.RequestTimeoutException = exports.NotAcceptableException = exports.MethodNotAllowedException = exports.NotFoundException = exports.ForbiddenException = exports.UnauthorizedException = exports.BadRequestException = exports.ValidationException = exports.HttpException = void 0;
|
|
3
|
+
exports.DiscoveryException = exports.ConfigProviderInstantiationException = exports.ConfigProviderNotFoundException = exports.ConfigProviderAlreadyRegisteredException = exports.getCatchMetadata = exports.CATCH_METADATA = exports.Catch = exports.createExceptionHandler = exports.GlobalExceptionFilter = exports.GatewayTimeoutException = exports.ServiceUnavailableException = exports.BadGatewayException = exports.NotImplementedException = exports.InternalServerErrorException = exports.TooManyRequestsException = exports.UnprocessableEntityException = exports.UnsupportedMediaTypeException = exports.PayloadTooLargeException = exports.GoneException = exports.ConflictException = exports.RequestTimeoutException = exports.NotAcceptableException = exports.MethodNotAllowedException = exports.NotFoundException = exports.ForbiddenException = exports.UnauthorizedException = exports.BadRequestException = exports.ValidationException = exports.HttpException = void 0;
|
|
4
4
|
var http_exception_1 = require("./http-exception");
|
|
5
5
|
Object.defineProperty(exports, "HttpException", { enumerable: true, get: function () { return http_exception_1.HttpException; } });
|
|
6
6
|
var validation_exception_1 = require("./validation.exception");
|
|
@@ -35,3 +35,5 @@ var config_exceptions_1 = require("./config.exceptions");
|
|
|
35
35
|
Object.defineProperty(exports, "ConfigProviderAlreadyRegisteredException", { enumerable: true, get: function () { return config_exceptions_1.ConfigProviderAlreadyRegisteredException; } });
|
|
36
36
|
Object.defineProperty(exports, "ConfigProviderNotFoundException", { enumerable: true, get: function () { return config_exceptions_1.ConfigProviderNotFoundException; } });
|
|
37
37
|
Object.defineProperty(exports, "ConfigProviderInstantiationException", { enumerable: true, get: function () { return config_exceptions_1.ConfigProviderInstantiationException; } });
|
|
38
|
+
var discovery_exception_1 = require("./discovery.exception");
|
|
39
|
+
Object.defineProperty(exports, "DiscoveryException", { enumerable: true, get: function () { return discovery_exception_1.DiscoveryException; } });
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import type { FastifyRequest, FastifyReply } from 'fastify';
|
|
2
2
|
import type { Constructor } from '../types';
|
|
3
|
+
export interface HttpArgumentsHost {
|
|
4
|
+
getRequest<T = FastifyRequest>(): T;
|
|
5
|
+
getResponse<T = FastifyReply>(): T;
|
|
6
|
+
}
|
|
3
7
|
export interface ExecutionContext {
|
|
8
|
+
switchToHttp(): HttpArgumentsHost;
|
|
4
9
|
getRequest<T = FastifyRequest>(): T;
|
|
5
10
|
getReply<T = FastifyReply>(): T;
|
|
6
11
|
getClass(): Constructor;
|
|
@@ -12,7 +17,9 @@ export declare class ExecutionContextImpl implements ExecutionContext {
|
|
|
12
17
|
private readonly reply;
|
|
13
18
|
private readonly controllerClass;
|
|
14
19
|
private readonly handlerName;
|
|
20
|
+
private readonly httpHost;
|
|
15
21
|
constructor(request: FastifyRequest, reply: FastifyReply, controllerClass: Constructor, handlerName: string | symbol);
|
|
22
|
+
switchToHttp(): HttpArgumentsHost;
|
|
16
23
|
getRequest<T = FastifyRequest>(): T;
|
|
17
24
|
getReply<T = FastifyReply>(): T;
|
|
18
25
|
getClass(): Constructor;
|
|
@@ -6,11 +6,19 @@ class ExecutionContextImpl {
|
|
|
6
6
|
reply;
|
|
7
7
|
controllerClass;
|
|
8
8
|
handlerName;
|
|
9
|
+
httpHost;
|
|
9
10
|
constructor(request, reply, controllerClass, handlerName) {
|
|
10
11
|
this.request = request;
|
|
11
12
|
this.reply = reply;
|
|
12
13
|
this.controllerClass = controllerClass;
|
|
13
14
|
this.handlerName = handlerName;
|
|
15
|
+
this.httpHost = {
|
|
16
|
+
getRequest: () => this.request,
|
|
17
|
+
getResponse: () => this.reply,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
switchToHttp() {
|
|
21
|
+
return this.httpHost;
|
|
14
22
|
}
|
|
15
23
|
getRequest() {
|
|
16
24
|
return this.request;
|
package/dist/core/index.d.ts
CHANGED
|
@@ -10,8 +10,10 @@ export * from './decorators';
|
|
|
10
10
|
export * from './exceptions';
|
|
11
11
|
export * from './guards';
|
|
12
12
|
export * from './middleware';
|
|
13
|
+
export * from './interceptors';
|
|
13
14
|
export * from './config';
|
|
14
15
|
export * from './metadata';
|
|
16
|
+
export * from './profiler';
|
|
15
17
|
export { z } from 'zod';
|
|
16
18
|
export type { ZodType, ZodSchema, ZodError, ZodIssue, infer as ZodInfer } from 'zod';
|
|
17
19
|
export type { FastifyInstance, FastifyRequest, FastifyReply } from 'fastify';
|
package/dist/core/index.js
CHANGED
|
@@ -27,7 +27,9 @@ __exportStar(require("./decorators"), exports);
|
|
|
27
27
|
__exportStar(require("./exceptions"), exports);
|
|
28
28
|
__exportStar(require("./guards"), exports);
|
|
29
29
|
__exportStar(require("./middleware"), exports);
|
|
30
|
+
__exportStar(require("./interceptors"), exports);
|
|
30
31
|
__exportStar(require("./config"), exports);
|
|
31
32
|
__exportStar(require("./metadata"), exports);
|
|
33
|
+
__exportStar(require("./profiler"), exports);
|
|
32
34
|
var zod_1 = require("zod");
|
|
33
35
|
Object.defineProperty(exports, "z", { enumerable: true, get: function () { return zod_1.z; } });
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getInterceptorsMetadata = exports.UseInterceptors = void 0;
|
|
4
|
+
var use_interceptors_decorator_1 = require("./use-interceptors.decorator");
|
|
5
|
+
Object.defineProperty(exports, "UseInterceptors", { enumerable: true, get: function () { return use_interceptors_decorator_1.UseInterceptors; } });
|
|
6
|
+
Object.defineProperty(exports, "getInterceptorsMetadata", { enumerable: true, get: function () { return use_interceptors_decorator_1.getInterceptorsMetadata; } });
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
import { Constructor } from '../types';
|
|
3
|
+
import type { Interceptor } from './interceptor.interface';
|
|
4
|
+
export type InterceptorClass = Constructor<Interceptor>;
|
|
5
|
+
export declare function UseInterceptors(...interceptors: InterceptorClass[]): ClassDecorator & MethodDecorator;
|
|
6
|
+
export declare function getInterceptorsMetadata(controllerClass: Constructor, methodName: string | symbol): InterceptorClass[];
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.UseInterceptors = UseInterceptors;
|
|
4
|
+
exports.getInterceptorsMetadata = getInterceptorsMetadata;
|
|
5
|
+
require("reflect-metadata");
|
|
6
|
+
const constants_1 = require("../constants");
|
|
7
|
+
function UseInterceptors(...interceptors) {
|
|
8
|
+
return (target, propertyKey, descriptor) => {
|
|
9
|
+
if (propertyKey && descriptor) {
|
|
10
|
+
const existingInterceptors = Reflect.getMetadata(constants_1.INTERCEPTORS_METADATA, target.constructor, propertyKey) ?? [];
|
|
11
|
+
Reflect.defineMetadata(constants_1.INTERCEPTORS_METADATA, [...existingInterceptors, ...interceptors], target.constructor, propertyKey);
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
const existingInterceptors = Reflect.getMetadata(constants_1.INTERCEPTORS_METADATA, target) ?? [];
|
|
15
|
+
Reflect.defineMetadata(constants_1.INTERCEPTORS_METADATA, [...existingInterceptors, ...interceptors], target);
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
function getInterceptorsMetadata(controllerClass, methodName) {
|
|
20
|
+
const controllerInterceptors = Reflect.getMetadata(constants_1.INTERCEPTORS_METADATA, controllerClass) ?? [];
|
|
21
|
+
const methodInterceptors = Reflect.getMetadata(constants_1.INTERCEPTORS_METADATA, controllerClass, methodName) ?? [];
|
|
22
|
+
return [...controllerInterceptors, ...methodInterceptors];
|
|
23
|
+
}
|
|
@@ -37,16 +37,21 @@ type Listener<E extends LifecycleEvent> = (payload: EventPayload[E]) => void | P
|
|
|
37
37
|
export declare class EventBus {
|
|
38
38
|
private listeners;
|
|
39
39
|
private onceListeners;
|
|
40
|
-
|
|
41
|
-
on<
|
|
42
|
-
|
|
43
|
-
once<
|
|
40
|
+
private ownerUnsubscribers;
|
|
41
|
+
on<E extends LifecycleEvent>(event: E, listener: Listener<E>, owner?: string): () => void;
|
|
42
|
+
on<T = unknown>(event: string, listener: (payload: T) => void | Promise<void>, owner?: string): () => void;
|
|
43
|
+
once<E extends LifecycleEvent>(event: E, listener: Listener<E>, owner?: string): void;
|
|
44
|
+
once<T = unknown>(event: string, listener: (payload: T) => void | Promise<void>, owner?: string): void;
|
|
44
45
|
emit<E extends LifecycleEvent>(event: E, payload: EventPayload[E]): Promise<void>;
|
|
45
46
|
emit<T = unknown>(event: string, payload: T): Promise<void>;
|
|
46
47
|
waitFor<E extends LifecycleEvent>(event: E): Promise<EventPayload[E]>;
|
|
47
48
|
waitFor<T = unknown>(event: string): Promise<T>;
|
|
48
49
|
off(event: string): void;
|
|
50
|
+
removeByOwner(owner: string): void;
|
|
49
51
|
clear(): void;
|
|
50
52
|
listenerCount(event: string): number;
|
|
53
|
+
totalListenerCount(): number;
|
|
54
|
+
listenerCountByOwner(owner: string): number;
|
|
55
|
+
getOwners(): string[];
|
|
51
56
|
}
|
|
52
57
|
export {};
|
|
@@ -11,29 +11,53 @@ const injectable_decorator_1 = require("../decorators/injectable.decorator");
|
|
|
11
11
|
let EventBus = class EventBus {
|
|
12
12
|
listeners = new Map();
|
|
13
13
|
onceListeners = new Map();
|
|
14
|
-
|
|
14
|
+
ownerUnsubscribers = new Map();
|
|
15
|
+
on(event, listener, owner) {
|
|
15
16
|
if (!this.listeners.has(event)) {
|
|
16
17
|
this.listeners.set(event, new Set());
|
|
17
18
|
}
|
|
18
|
-
|
|
19
|
-
|
|
19
|
+
const tracked = { listener, owner };
|
|
20
|
+
this.listeners.get(event).add(tracked);
|
|
21
|
+
const unsubscribe = () => {
|
|
22
|
+
this.listeners.get(event)?.delete(tracked);
|
|
23
|
+
if (owner) {
|
|
24
|
+
this.ownerUnsubscribers.get(owner)?.delete(unsubscribe);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
if (owner) {
|
|
28
|
+
if (!this.ownerUnsubscribers.has(owner)) {
|
|
29
|
+
this.ownerUnsubscribers.set(owner, new Set());
|
|
30
|
+
}
|
|
31
|
+
this.ownerUnsubscribers.get(owner).add(unsubscribe);
|
|
32
|
+
}
|
|
33
|
+
return unsubscribe;
|
|
20
34
|
}
|
|
21
|
-
once(event, listener) {
|
|
35
|
+
once(event, listener, owner) {
|
|
22
36
|
if (!this.onceListeners.has(event)) {
|
|
23
37
|
this.onceListeners.set(event, new Set());
|
|
24
38
|
}
|
|
25
|
-
|
|
39
|
+
const tracked = { listener, owner };
|
|
40
|
+
this.onceListeners.get(event).add(tracked);
|
|
41
|
+
if (owner) {
|
|
42
|
+
if (!this.ownerUnsubscribers.has(owner)) {
|
|
43
|
+
this.ownerUnsubscribers.set(owner, new Set());
|
|
44
|
+
}
|
|
45
|
+
const unsubscribe = () => {
|
|
46
|
+
this.onceListeners.get(event)?.delete(tracked);
|
|
47
|
+
};
|
|
48
|
+
this.ownerUnsubscribers.get(owner).add(unsubscribe);
|
|
49
|
+
}
|
|
26
50
|
}
|
|
27
51
|
async emit(event, payload) {
|
|
28
52
|
const listeners = this.listeners.get(event);
|
|
29
53
|
if (listeners) {
|
|
30
|
-
for (const listener of listeners) {
|
|
54
|
+
for (const { listener } of listeners) {
|
|
31
55
|
await listener(payload);
|
|
32
56
|
}
|
|
33
57
|
}
|
|
34
58
|
const onceListeners = this.onceListeners.get(event);
|
|
35
59
|
if (onceListeners) {
|
|
36
|
-
for (const listener of onceListeners) {
|
|
60
|
+
for (const { listener } of onceListeners) {
|
|
37
61
|
await listener(payload);
|
|
38
62
|
}
|
|
39
63
|
this.onceListeners.delete(event);
|
|
@@ -46,14 +70,40 @@ let EventBus = class EventBus {
|
|
|
46
70
|
this.listeners.delete(event);
|
|
47
71
|
this.onceListeners.delete(event);
|
|
48
72
|
}
|
|
73
|
+
removeByOwner(owner) {
|
|
74
|
+
const unsubscribers = this.ownerUnsubscribers.get(owner);
|
|
75
|
+
if (unsubscribers) {
|
|
76
|
+
for (const unsubscribe of unsubscribers) {
|
|
77
|
+
unsubscribe();
|
|
78
|
+
}
|
|
79
|
+
this.ownerUnsubscribers.delete(owner);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
49
82
|
clear() {
|
|
50
83
|
this.listeners.clear();
|
|
51
84
|
this.onceListeners.clear();
|
|
85
|
+
this.ownerUnsubscribers.clear();
|
|
52
86
|
}
|
|
53
87
|
listenerCount(event) {
|
|
54
88
|
return (this.listeners.get(event)?.size ?? 0) +
|
|
55
89
|
(this.onceListeners.get(event)?.size ?? 0);
|
|
56
90
|
}
|
|
91
|
+
totalListenerCount() {
|
|
92
|
+
let count = 0;
|
|
93
|
+
for (const listeners of this.listeners.values()) {
|
|
94
|
+
count += listeners.size;
|
|
95
|
+
}
|
|
96
|
+
for (const listeners of this.onceListeners.values()) {
|
|
97
|
+
count += listeners.size;
|
|
98
|
+
}
|
|
99
|
+
return count;
|
|
100
|
+
}
|
|
101
|
+
listenerCountByOwner(owner) {
|
|
102
|
+
return this.ownerUnsubscribers.get(owner)?.size ?? 0;
|
|
103
|
+
}
|
|
104
|
+
getOwners() {
|
|
105
|
+
return [...this.ownerUnsubscribers.keys()];
|
|
106
|
+
}
|
|
57
107
|
};
|
|
58
108
|
exports.EventBus = EventBus;
|
|
59
109
|
exports.EventBus = EventBus = __decorate([
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getGlobalProfiler = exports.setGlobalProfiler = exports.profiler = exports.PerformanceProfiler = void 0;
|
|
4
|
+
var performance_profiler_1 = require("./performance-profiler");
|
|
5
|
+
Object.defineProperty(exports, "PerformanceProfiler", { enumerable: true, get: function () { return performance_profiler_1.PerformanceProfiler; } });
|
|
6
|
+
Object.defineProperty(exports, "profiler", { enumerable: true, get: function () { return performance_profiler_1.profiler; } });
|
|
7
|
+
Object.defineProperty(exports, "setGlobalProfiler", { enumerable: true, get: function () { return performance_profiler_1.setGlobalProfiler; } });
|
|
8
|
+
Object.defineProperty(exports, "getGlobalProfiler", { enumerable: true, get: function () { return performance_profiler_1.getGlobalProfiler; } });
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { EventBus } from '../lifecycle/event-bus';
|
|
2
|
+
export interface PerformanceMetric {
|
|
3
|
+
name: string;
|
|
4
|
+
duration: number;
|
|
5
|
+
startTime: number;
|
|
6
|
+
metadata?: Record<string, unknown>;
|
|
7
|
+
}
|
|
8
|
+
export interface RouteMetric extends PerformanceMetric {
|
|
9
|
+
method: string;
|
|
10
|
+
path: string;
|
|
11
|
+
statusCode: number;
|
|
12
|
+
}
|
|
13
|
+
export interface BootstrapMetrics {
|
|
14
|
+
total: number;
|
|
15
|
+
discovery: number;
|
|
16
|
+
containerInit: number;
|
|
17
|
+
routeRegistration: number;
|
|
18
|
+
lifecycleHooks: number;
|
|
19
|
+
}
|
|
20
|
+
export declare class PerformanceProfiler {
|
|
21
|
+
private enabled;
|
|
22
|
+
private eventBus?;
|
|
23
|
+
private listeners;
|
|
24
|
+
private bootstrapMetrics;
|
|
25
|
+
constructor(options?: {
|
|
26
|
+
enabled?: boolean;
|
|
27
|
+
eventBus?: EventBus;
|
|
28
|
+
});
|
|
29
|
+
setEnabled(enabled: boolean): void;
|
|
30
|
+
isEnabled(): boolean;
|
|
31
|
+
startTimer(name: string): (metadata?: Record<string, unknown>) => PerformanceMetric | null;
|
|
32
|
+
measure<T>(name: string, fn: () => T | Promise<T>): Promise<T>;
|
|
33
|
+
recordRouteMetric(metric: RouteMetric): void;
|
|
34
|
+
recordBootstrapPhase(phase: keyof BootstrapMetrics, duration: number): void;
|
|
35
|
+
getBootstrapMetrics(): Partial<BootstrapMetrics>;
|
|
36
|
+
onMetric(listener: (metric: PerformanceMetric) => void): () => void;
|
|
37
|
+
private emitMetric;
|
|
38
|
+
createConsoleTimer(prefix?: string): (name: string) => (metadata?: Record<string, unknown>) => void;
|
|
39
|
+
}
|
|
40
|
+
export declare let profiler: PerformanceProfiler;
|
|
41
|
+
export declare function setGlobalProfiler(newProfiler: PerformanceProfiler): void;
|
|
42
|
+
export declare function getGlobalProfiler(): PerformanceProfiler;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.profiler = exports.PerformanceProfiler = void 0;
|
|
4
|
+
exports.setGlobalProfiler = setGlobalProfiler;
|
|
5
|
+
exports.getGlobalProfiler = getGlobalProfiler;
|
|
6
|
+
class PerformanceProfiler {
|
|
7
|
+
enabled = true;
|
|
8
|
+
eventBus;
|
|
9
|
+
listeners = [];
|
|
10
|
+
bootstrapMetrics = {};
|
|
11
|
+
constructor(options) {
|
|
12
|
+
this.enabled = options?.enabled ?? true;
|
|
13
|
+
this.eventBus = options?.eventBus;
|
|
14
|
+
}
|
|
15
|
+
setEnabled(enabled) {
|
|
16
|
+
this.enabled = enabled;
|
|
17
|
+
}
|
|
18
|
+
isEnabled() {
|
|
19
|
+
return this.enabled;
|
|
20
|
+
}
|
|
21
|
+
startTimer(name) {
|
|
22
|
+
if (!this.enabled) {
|
|
23
|
+
return () => null;
|
|
24
|
+
}
|
|
25
|
+
const startTime = performance.now();
|
|
26
|
+
const startTimestamp = Date.now();
|
|
27
|
+
return (metadata) => {
|
|
28
|
+
const duration = performance.now() - startTime;
|
|
29
|
+
const metric = {
|
|
30
|
+
name,
|
|
31
|
+
duration,
|
|
32
|
+
startTime: startTimestamp,
|
|
33
|
+
metadata,
|
|
34
|
+
};
|
|
35
|
+
this.emitMetric(metric);
|
|
36
|
+
return metric;
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
async measure(name, fn) {
|
|
40
|
+
const end = this.startTimer(name);
|
|
41
|
+
try {
|
|
42
|
+
const result = await fn();
|
|
43
|
+
end();
|
|
44
|
+
return result;
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
end({ error: true });
|
|
48
|
+
throw error;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
recordRouteMetric(metric) {
|
|
52
|
+
if (!this.enabled)
|
|
53
|
+
return;
|
|
54
|
+
this.emitMetric(metric);
|
|
55
|
+
this.eventBus?.emit('profiler:route', metric);
|
|
56
|
+
}
|
|
57
|
+
recordBootstrapPhase(phase, duration) {
|
|
58
|
+
this.bootstrapMetrics[phase] = duration;
|
|
59
|
+
}
|
|
60
|
+
getBootstrapMetrics() {
|
|
61
|
+
return { ...this.bootstrapMetrics };
|
|
62
|
+
}
|
|
63
|
+
onMetric(listener) {
|
|
64
|
+
this.listeners.push(listener);
|
|
65
|
+
return () => {
|
|
66
|
+
const index = this.listeners.indexOf(listener);
|
|
67
|
+
if (index !== -1) {
|
|
68
|
+
this.listeners.splice(index, 1);
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
emitMetric(metric) {
|
|
73
|
+
for (const listener of this.listeners) {
|
|
74
|
+
try {
|
|
75
|
+
listener(metric);
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
this.eventBus?.emit('profiler:metric', metric);
|
|
81
|
+
}
|
|
82
|
+
createConsoleTimer(prefix = '[Rikta]') {
|
|
83
|
+
return (name) => {
|
|
84
|
+
const end = this.startTimer(name);
|
|
85
|
+
return (metadata) => {
|
|
86
|
+
const metric = end(metadata);
|
|
87
|
+
if (metric) {
|
|
88
|
+
console.log(`${prefix} ${metric.name}: ${metric.duration.toFixed(2)}ms`);
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
exports.PerformanceProfiler = PerformanceProfiler;
|
|
95
|
+
exports.profiler = new PerformanceProfiler();
|
|
96
|
+
function setGlobalProfiler(newProfiler) {
|
|
97
|
+
exports.profiler = newProfiler;
|
|
98
|
+
}
|
|
99
|
+
function getGlobalProfiler() {
|
|
100
|
+
return exports.profiler;
|
|
101
|
+
}
|
package/dist/core/registry.d.ts
CHANGED
|
@@ -3,12 +3,18 @@ interface ConfigProviderRegistration {
|
|
|
3
3
|
token: string;
|
|
4
4
|
providerClass: Constructor;
|
|
5
5
|
}
|
|
6
|
+
interface AbstractImplementation {
|
|
7
|
+
implementation: Constructor;
|
|
8
|
+
isPrimary: boolean;
|
|
9
|
+
name?: string;
|
|
10
|
+
}
|
|
6
11
|
declare class Registry {
|
|
7
12
|
private static instance;
|
|
8
13
|
private controllers;
|
|
9
14
|
private providers;
|
|
10
15
|
private customProviders;
|
|
11
16
|
private configProviderMap;
|
|
17
|
+
private abstractImplementations;
|
|
12
18
|
private constructor();
|
|
13
19
|
static getInstance(): Registry;
|
|
14
20
|
static reset(): void;
|
|
@@ -24,6 +30,12 @@ declare class Registry {
|
|
|
24
30
|
registerConfigProvider(token: string, providerClass: Constructor): void;
|
|
25
31
|
getConfigProviderRegistrations(): ConfigProviderRegistration[];
|
|
26
32
|
clearConfigProviders(): void;
|
|
33
|
+
registerAbstractImplementation(abstractClass: Constructor, implementation: Constructor, name?: string): void;
|
|
34
|
+
setImplementationName(abstractClass: Constructor, implementation: Constructor, name: string): void;
|
|
35
|
+
setPrimaryImplementation(abstractClass: Constructor, implementation: Constructor): void;
|
|
36
|
+
getImplementations(abstractClass: Constructor): AbstractImplementation[];
|
|
37
|
+
hasImplementation(abstractClass: Constructor): boolean;
|
|
38
|
+
clearAbstractImplementations(): void;
|
|
27
39
|
}
|
|
28
40
|
export declare const registry: Registry;
|
|
29
41
|
export { Registry };
|
package/dist/core/registry.js
CHANGED
|
@@ -8,6 +8,7 @@ class Registry {
|
|
|
8
8
|
providers = new Set();
|
|
9
9
|
customProviders = new Set();
|
|
10
10
|
configProviderMap = new Map();
|
|
11
|
+
abstractImplementations = new Map();
|
|
11
12
|
constructor() { }
|
|
12
13
|
static getInstance() {
|
|
13
14
|
if (!Registry.instance) {
|
|
@@ -62,6 +63,50 @@ class Registry {
|
|
|
62
63
|
clearConfigProviders() {
|
|
63
64
|
this.configProviderMap.clear();
|
|
64
65
|
}
|
|
66
|
+
registerAbstractImplementation(abstractClass, implementation, name) {
|
|
67
|
+
const implementations = this.abstractImplementations.get(abstractClass) ?? [];
|
|
68
|
+
const existing = implementations.find(i => i.implementation === implementation);
|
|
69
|
+
if (!existing) {
|
|
70
|
+
implementations.push({
|
|
71
|
+
implementation,
|
|
72
|
+
isPrimary: false,
|
|
73
|
+
name,
|
|
74
|
+
});
|
|
75
|
+
this.abstractImplementations.set(abstractClass, implementations);
|
|
76
|
+
}
|
|
77
|
+
else if (name && !existing.name) {
|
|
78
|
+
existing.name = name;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
setImplementationName(abstractClass, implementation, name) {
|
|
82
|
+
const implementations = this.abstractImplementations.get(abstractClass);
|
|
83
|
+
if (!implementations) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
const impl = implementations.find(i => i.implementation === implementation);
|
|
87
|
+
if (impl) {
|
|
88
|
+
impl.name = name;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
setPrimaryImplementation(abstractClass, implementation) {
|
|
92
|
+
const implementations = this.abstractImplementations.get(abstractClass);
|
|
93
|
+
if (!implementations) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
for (const impl of implementations) {
|
|
97
|
+
impl.isPrimary = impl.implementation === implementation;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
getImplementations(abstractClass) {
|
|
101
|
+
return this.abstractImplementations.get(abstractClass) ?? [];
|
|
102
|
+
}
|
|
103
|
+
hasImplementation(abstractClass) {
|
|
104
|
+
const implementations = this.abstractImplementations.get(abstractClass);
|
|
105
|
+
return !!implementations && implementations.length > 0;
|
|
106
|
+
}
|
|
107
|
+
clearAbstractImplementations() {
|
|
108
|
+
this.abstractImplementations.clear();
|
|
109
|
+
}
|
|
65
110
|
}
|
|
66
111
|
exports.Registry = Registry;
|
|
67
112
|
exports.registry = Registry.getInstance();
|
|
@@ -8,7 +8,15 @@ export declare class Router {
|
|
|
8
8
|
private readonly globalPrefix;
|
|
9
9
|
private readonly guardCache;
|
|
10
10
|
private readonly middlewareCache;
|
|
11
|
+
private readonly interceptorCache;
|
|
11
12
|
constructor(server: FastifyInstance, container: Container, globalPrefix?: string);
|
|
13
|
+
clearGuardCache(): void;
|
|
14
|
+
clearMiddlewareCache(): void;
|
|
15
|
+
clearInterceptorCache(): void;
|
|
16
|
+
clearAllCaches(): void;
|
|
17
|
+
getGuardCacheSize(): number;
|
|
18
|
+
getMiddlewareCacheSize(): number;
|
|
19
|
+
getInterceptorCacheSize(): number;
|
|
12
20
|
registerController(controllerClass: Constructor, silent?: boolean): void;
|
|
13
21
|
private registerRoute;
|
|
14
22
|
private compileParamResolvers;
|
|
@@ -18,5 +26,7 @@ export declare class Router {
|
|
|
18
26
|
private executeGuardsOptimized;
|
|
19
27
|
private resolveMiddlewareInstances;
|
|
20
28
|
private executeMiddlewareChain;
|
|
29
|
+
private resolveInterceptorInstances;
|
|
30
|
+
private executeInterceptorChain;
|
|
21
31
|
private buildPath;
|
|
22
32
|
}
|