@xrystal/core 3.20.7 → 3.21.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/package.json +13 -20
- package/source/loader/controller/index.d.ts +21 -22
- package/source/loader/controller/index.js +9 -20
- package/source/loader/logger/index.d.ts +1 -1
- package/source/loader/logger/index.js +10 -8
- package/source/loader/system/index.js +1 -1
- package/source/project/index.js +3 -1
- package/source/utils/models/classes/class.x.d.ts +8 -4
- package/source/utils/models/classes/class.x.js +77 -88
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"author": "Yusuf Yasir KAYGUSUZ",
|
|
3
3
|
"name": "@xrystal/core",
|
|
4
|
-
"version": "3.
|
|
4
|
+
"version": "3.21.0",
|
|
5
5
|
"description": "Project core for xrystal",
|
|
6
6
|
"publishConfig": {
|
|
7
7
|
"access": "public",
|
|
@@ -37,34 +37,27 @@
|
|
|
37
37
|
"start": "bun --env-file=../infrastructer/x/environments/.global.env --env-file=../infrastructer/x/environments/.dev.env source/index.js"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"
|
|
41
|
-
"@types/yaml": "^1.9.7",
|
|
40
|
+
"lodash": "^4.17.23",
|
|
42
41
|
"awilix": "^12.0.5",
|
|
43
|
-
"
|
|
44
|
-
"commander": "^13.0.0",
|
|
45
|
-
"ejs": "^3.1.9",
|
|
42
|
+
"yaml": "^2.5.0",
|
|
46
43
|
"handlebars": "^4.7.8",
|
|
47
|
-
"
|
|
44
|
+
"winston": "^3.19.0",
|
|
45
|
+
"winston-daily-rotate-file": "^5.0.0",
|
|
46
|
+
"winston-mongodb": "^7.0.1",
|
|
47
|
+
"kafkajs": "^2.2.4",
|
|
48
48
|
"i18next": "^25.6.3",
|
|
49
49
|
"i18next-fs-backend": "^2.6.1",
|
|
50
50
|
"i18next-http-middleware": "^3.8.2",
|
|
51
|
-
"kafkajs": "^2.2.4",
|
|
52
|
-
"lodash": "^4.17.23",
|
|
53
|
-
"moment-timezone": "^0.6.0",
|
|
54
|
-
"npm": "^11.7.0",
|
|
55
51
|
"ora": "^9.0.0",
|
|
56
|
-
"picocolors": "^1.1.1",
|
|
57
52
|
"qs": "^6.14.1",
|
|
58
53
|
"soap": "^1.6.3",
|
|
59
|
-
"
|
|
60
|
-
"
|
|
61
|
-
"
|
|
62
|
-
"yaml": "^2.5.0"
|
|
54
|
+
"chalk": "^5.6.2",
|
|
55
|
+
"commander": "^13.0.0",
|
|
56
|
+
"picocolors": "^1.1.1"
|
|
63
57
|
},
|
|
64
58
|
"devDependencies": {
|
|
65
|
-
"@types/
|
|
66
|
-
"@types/
|
|
67
|
-
"@types/
|
|
68
|
-
"typescript": "^5.5.3"
|
|
59
|
+
"@types/lodash": "^4.17.23",
|
|
60
|
+
"@types/yaml": "^1.9.7",
|
|
61
|
+
"@types/bun": "^1.3.5"
|
|
69
62
|
}
|
|
70
63
|
}
|
|
@@ -26,26 +26,9 @@ export declare const getControllerCtx: () => {
|
|
|
26
26
|
_isRaw?: boolean;
|
|
27
27
|
};
|
|
28
28
|
};
|
|
29
|
-
export declare
|
|
30
|
-
export interface CustomRequest {
|
|
31
|
-
accounts?: any;
|
|
32
|
-
url: string;
|
|
33
|
-
method: string;
|
|
34
|
-
headers: Record<string, any>;
|
|
35
|
-
body?: any;
|
|
36
|
-
params: Record<string, any>;
|
|
37
|
-
query: Record<string, any>;
|
|
38
|
-
lang: string;
|
|
39
|
-
t: (k: string, args?: any) => string;
|
|
40
|
-
}
|
|
41
|
-
export interface CustomResponse {
|
|
42
|
-
status: (code: number) => CustomResponse;
|
|
43
|
-
send: (data: any) => any;
|
|
44
|
-
json: (data: any) => any;
|
|
45
|
-
locals: Record<string, any>;
|
|
46
|
-
}
|
|
47
|
-
declare abstract class Controller {
|
|
29
|
+
export declare abstract class Controller {
|
|
48
30
|
protected logger: LoggerService;
|
|
31
|
+
protected systemService: SystemService;
|
|
49
32
|
protected supportedProtocols: ProtocolEnum[];
|
|
50
33
|
protected get protocol(): ProtocolEnum;
|
|
51
34
|
protected get currentStore(): {
|
|
@@ -64,9 +47,9 @@ declare abstract class Controller {
|
|
|
64
47
|
protected get res(): CustomResponse;
|
|
65
48
|
}
|
|
66
49
|
export declare abstract class ControllerService extends Controller implements IService<any> {
|
|
67
|
-
|
|
68
|
-
constructor({ systemService }: {
|
|
50
|
+
constructor({ systemService, loggerService }: {
|
|
69
51
|
systemService: SystemService;
|
|
52
|
+
loggerService: LoggerService;
|
|
70
53
|
});
|
|
71
54
|
load(): Promise<void>;
|
|
72
55
|
schema({ checks, logic, response }: {
|
|
@@ -75,4 +58,20 @@ export declare abstract class ControllerService extends Controller implements IS
|
|
|
75
58
|
response?: (args: any) => Promise<any>;
|
|
76
59
|
}): Promise<any>;
|
|
77
60
|
}
|
|
78
|
-
export
|
|
61
|
+
export interface CustomRequest {
|
|
62
|
+
accounts?: any;
|
|
63
|
+
url: string;
|
|
64
|
+
method: string;
|
|
65
|
+
headers: Record<string, any>;
|
|
66
|
+
body?: any;
|
|
67
|
+
params: Record<string, any>;
|
|
68
|
+
query: Record<string, any>;
|
|
69
|
+
lang: string;
|
|
70
|
+
t: (k: string, args?: any) => string;
|
|
71
|
+
}
|
|
72
|
+
export interface CustomResponse {
|
|
73
|
+
status: (code: number) => CustomResponse;
|
|
74
|
+
send: (data: any) => any;
|
|
75
|
+
json: (data: any) => any;
|
|
76
|
+
locals: Record<string, any>;
|
|
77
|
+
}
|
|
@@ -1,17 +1,10 @@
|
|
|
1
1
|
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
2
|
-
import { ProtocolEnum, responseMessageHelper, ResponseSchema
|
|
3
|
-
import LoggerService from '../logger';
|
|
2
|
+
import { LoggerLayerEnum, ProtocolEnum, responseMessageHelper, ResponseSchema } from '../../utils/index';
|
|
4
3
|
export const controllerContextStorage = new AsyncLocalStorage();
|
|
5
4
|
export const getControllerCtx = () => controllerContextStorage.getStore();
|
|
6
|
-
export
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
store.protocol = protocol;
|
|
10
|
-
}
|
|
11
|
-
return await callback();
|
|
12
|
-
};
|
|
13
|
-
class Controller {
|
|
14
|
-
logger = x.get(LoggerService);
|
|
5
|
+
export class Controller {
|
|
6
|
+
logger;
|
|
7
|
+
systemService;
|
|
15
8
|
supportedProtocols = [ProtocolEnum.HTTP, ProtocolEnum.WEBSOCKET];
|
|
16
9
|
get protocol() {
|
|
17
10
|
return this.currentStore?.protocol || ProtocolEnum.HTTP;
|
|
@@ -79,14 +72,14 @@ class Controller {
|
|
|
79
72
|
}
|
|
80
73
|
}
|
|
81
74
|
export class ControllerService extends Controller {
|
|
82
|
-
systemService
|
|
83
|
-
constructor({ systemService }) {
|
|
75
|
+
constructor({ systemService, loggerService }) {
|
|
84
76
|
super();
|
|
85
77
|
this.systemService = systemService;
|
|
78
|
+
this.logger = loggerService;
|
|
86
79
|
}
|
|
87
80
|
async load() {
|
|
88
|
-
const protocols = this.systemService
|
|
89
|
-
this.supportedProtocols = Array.isArray(protocols) ? protocols : [protocols];
|
|
81
|
+
const protocols = this.systemService?.tmp?.configs?.loaders?.controller?.protocols;
|
|
82
|
+
this.supportedProtocols = Array.isArray(protocols) ? protocols : [protocols || ProtocolEnum.HTTP];
|
|
90
83
|
}
|
|
91
84
|
async schema({ checks, logic, response }) {
|
|
92
85
|
try {
|
|
@@ -153,10 +146,7 @@ export class ControllerService extends Controller {
|
|
|
153
146
|
}).getResponse);
|
|
154
147
|
}
|
|
155
148
|
catch (error) {
|
|
156
|
-
this.logger
|
|
157
|
-
level: 'error',
|
|
158
|
-
message: `Controller Error: ${error.message}`
|
|
159
|
-
});
|
|
149
|
+
this.logger?.log(LoggerLayerEnum.ERROR, `Controller Error: ${error.message}`);
|
|
160
150
|
return this.res.status(500).send(new ResponseSchema({
|
|
161
151
|
status: false,
|
|
162
152
|
message: error.message,
|
|
@@ -165,4 +155,3 @@ export class ControllerService extends Controller {
|
|
|
165
155
|
}
|
|
166
156
|
}
|
|
167
157
|
}
|
|
168
|
-
export { Controller };
|
|
@@ -26,7 +26,7 @@ export default class LoggerService implements IService<any> {
|
|
|
26
26
|
systemService: SystemService;
|
|
27
27
|
configsService: ConfigsService;
|
|
28
28
|
});
|
|
29
|
-
load: (
|
|
29
|
+
load: () => Promise<void>;
|
|
30
30
|
winstonLoader: ({ loadPath, loggerLevel }: {
|
|
31
31
|
loadPath: string;
|
|
32
32
|
loggerLevel: string;
|
|
@@ -43,18 +43,18 @@ export default class LoggerService {
|
|
|
43
43
|
constructor({ systemService, configsService }) {
|
|
44
44
|
this.#systemService = systemService;
|
|
45
45
|
this.#configsService = configsService;
|
|
46
|
-
|
|
46
|
+
}
|
|
47
|
+
load = async () => {
|
|
48
|
+
this.serviceName = this.#systemService?.tmp?.configs?.service;
|
|
49
|
+
this.kafkaLogsTopic = this.#configsService?.all?.kafkaLogsTopic;
|
|
47
50
|
winston.addColors(customColors);
|
|
48
51
|
this.winston = winston.createLogger({
|
|
49
|
-
level: this.#configsService
|
|
52
|
+
level: this.#configsService?.all?.systemLoggerLayer || 'info',
|
|
50
53
|
levels: customLevels,
|
|
51
54
|
format: this.getConsoleFormat(),
|
|
52
55
|
transports: [new winston.transports.Console()]
|
|
53
56
|
});
|
|
54
|
-
|
|
55
|
-
load = async ({}) => {
|
|
56
|
-
const loggersConfigs = this.#systemService.tmp.configs.loaders.loggers;
|
|
57
|
-
this.serviceName = this.#systemService.tmp.configs.service;
|
|
57
|
+
const loggersConfigs = this.#systemService?.tmp?.configs?.loaders?.loggers;
|
|
58
58
|
const { kafkaBrokers, isKafkaPassive } = this.#configsService.all;
|
|
59
59
|
const brokers = kafkaBrokers ? String(kafkaBrokers).split(",").map((b) => b.trim()) : [];
|
|
60
60
|
const isKafkaEnabled = isKafkaPassive === false && brokers.length > 0;
|
|
@@ -76,9 +76,11 @@ export default class LoggerService {
|
|
|
76
76
|
this.isKafkaReady = false;
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
|
+
const logPath = loggersConfigs?.loadPath || "logs";
|
|
80
|
+
const loggerLevel = loggersConfigs?.loggerLevel || "info";
|
|
79
81
|
this.winstonLoader({
|
|
80
|
-
loadPath: path.join(this.#configsService.all.rootFolderPath,
|
|
81
|
-
loggerLevel:
|
|
82
|
+
loadPath: path.join(this.#configsService.all.rootFolderPath, logPath),
|
|
83
|
+
loggerLevel: loggerLevel
|
|
82
84
|
});
|
|
83
85
|
};
|
|
84
86
|
winstonLoader = ({ loadPath, loggerLevel }) => {
|
|
@@ -7,8 +7,8 @@ export default class SystemService {
|
|
|
7
7
|
load = async ({ core }) => {
|
|
8
8
|
this._core = core;
|
|
9
9
|
this._tmp = this._core._;
|
|
10
|
-
await this.initializeKafkaInfrastructure();
|
|
11
10
|
await this._systemLoader({});
|
|
11
|
+
await this.initializeKafkaInfrastructure();
|
|
12
12
|
};
|
|
13
13
|
initializeKafkaInfrastructure = async () => {
|
|
14
14
|
const { kafkaBrokers, kafkaTopics, isKafkaPassive, serviceName } = {
|
package/source/project/index.js
CHANGED
|
@@ -16,7 +16,9 @@ const coreLoader = async ({}) => {
|
|
|
16
16
|
await (await x.load([
|
|
17
17
|
path.join(__dirname, '..', 'loader', '**/*.{ts,js}'),
|
|
18
18
|
], {
|
|
19
|
-
exclude: [
|
|
19
|
+
exclude: [
|
|
20
|
+
path.join(__dirname, '..', 'utils', '**/class.x.{ts,js}'),
|
|
21
|
+
]
|
|
20
22
|
}))
|
|
21
23
|
.initialize([
|
|
22
24
|
{
|
|
@@ -1,19 +1,23 @@
|
|
|
1
1
|
import { AwilixContainer, LifetimeType } from 'awilix';
|
|
2
|
+
type Constructor<T> = new (...args: any[]) => T;
|
|
3
|
+
type AbstractConstructor<T> = abstract new (...args: any[]) => T;
|
|
2
4
|
declare abstract class XHelper {
|
|
3
5
|
protected checkRegistration(container: AwilixContainer, name: string): boolean;
|
|
4
6
|
}
|
|
5
7
|
declare class X extends XHelper {
|
|
6
8
|
private container;
|
|
7
9
|
private initializedNames;
|
|
10
|
+
private loadedPaths;
|
|
11
|
+
private registeredClasses;
|
|
12
|
+
private isInitializing;
|
|
8
13
|
constructor();
|
|
9
|
-
private
|
|
14
|
+
private getName;
|
|
10
15
|
load(patterns: string | string[], options?: {
|
|
11
16
|
verbose?: boolean;
|
|
12
17
|
exclude?: string | Function | (string | Function)[];
|
|
13
18
|
lifetime?: LifetimeType;
|
|
14
19
|
}): Promise<this>;
|
|
15
20
|
register(Dependency: any, lifetime?: LifetimeType): this;
|
|
16
|
-
registerAll(dependencies: any[], lifetime?: LifetimeType): this;
|
|
17
21
|
registerInstance(name: string, instance: any): this;
|
|
18
22
|
initialize<T = any>(input?: {
|
|
19
23
|
service: any;
|
|
@@ -22,8 +26,8 @@ declare class X extends XHelper {
|
|
|
22
26
|
service: any;
|
|
23
27
|
props?: T;
|
|
24
28
|
}[], verbose?: boolean): Promise<this>;
|
|
25
|
-
|
|
26
|
-
|
|
29
|
+
get<T>(target: Constructor<T> | AbstractConstructor<T> | string): T;
|
|
30
|
+
shutdown(): Promise<void>;
|
|
27
31
|
get cradle(): any;
|
|
28
32
|
}
|
|
29
33
|
declare const _default: X;
|
|
@@ -3,12 +3,15 @@ import path from 'node:path';
|
|
|
3
3
|
import { pathToFileURL } from 'node:url';
|
|
4
4
|
class XHelper {
|
|
5
5
|
checkRegistration(container, name) {
|
|
6
|
-
return !!container.registrations[name]
|
|
6
|
+
return !!container.registrations[name];
|
|
7
7
|
}
|
|
8
8
|
}
|
|
9
9
|
class X extends XHelper {
|
|
10
10
|
container;
|
|
11
11
|
initializedNames = new Set();
|
|
12
|
+
loadedPaths = new Set();
|
|
13
|
+
registeredClasses = new Set();
|
|
14
|
+
isInitializing = false;
|
|
12
15
|
constructor() {
|
|
13
16
|
super();
|
|
14
17
|
this.container = createContainer({
|
|
@@ -16,18 +19,19 @@ class X extends XHelper {
|
|
|
16
19
|
strict: true
|
|
17
20
|
});
|
|
18
21
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
22
|
+
getName(target) {
|
|
23
|
+
if (typeof target === 'string')
|
|
24
|
+
return target.charAt(0).toLowerCase() + target.slice(1);
|
|
25
|
+
if (typeof target === 'function' && target.name)
|
|
26
|
+
return target.name.charAt(0).toLowerCase() + target.name.slice(1);
|
|
27
|
+
return '';
|
|
23
28
|
}
|
|
24
29
|
async load(patterns, options = {}) {
|
|
25
30
|
const { verbose = false, exclude = [], lifetime = Lifetime.SINGLETON } = options;
|
|
26
31
|
const cwd = process.cwd();
|
|
27
|
-
const excludeList = Array.isArray(exclude) ? exclude : [exclude];
|
|
28
32
|
const resolvedPatterns = (Array.isArray(patterns) ? patterns : [patterns]).map(p => {
|
|
29
33
|
const resolved = path.isAbsolute(p) ? p : path.resolve(cwd, p);
|
|
30
|
-
return resolved.replace(/\\/g, '/');
|
|
34
|
+
return resolved.replace(/\\/g, '/').toLowerCase();
|
|
31
35
|
});
|
|
32
36
|
let modules = [];
|
|
33
37
|
try {
|
|
@@ -37,18 +41,10 @@ class X extends XHelper {
|
|
|
37
41
|
return this;
|
|
38
42
|
}
|
|
39
43
|
for (const m of modules) {
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
if (normalizedMPath === __filename.replace(/\\/g, '/') || normalizedMPath.endsWith('.d.ts'))
|
|
44
|
+
const normalizedMPath = m.path.replace(/\\/g, '/').toLowerCase();
|
|
45
|
+
if (this.loadedPaths.has(normalizedMPath))
|
|
43
46
|
continue;
|
|
44
|
-
|
|
45
|
-
if (typeof ex === 'string') {
|
|
46
|
-
const normalizedEx = ex.replace(/\\/g, '/');
|
|
47
|
-
return normalizedMPath.includes(normalizedEx) || m.name === ex;
|
|
48
|
-
}
|
|
49
|
-
return false;
|
|
50
|
-
});
|
|
51
|
-
if (isPathExcluded)
|
|
47
|
+
if (normalizedMPath === __filename.replace(/\\/g, '/').toLowerCase() || normalizedMPath.endsWith('.d.ts'))
|
|
52
48
|
continue;
|
|
53
49
|
try {
|
|
54
50
|
const fileUrl = pathToFileURL(m.path).href;
|
|
@@ -57,116 +53,109 @@ class X extends XHelper {
|
|
|
57
53
|
if (!dependency) {
|
|
58
54
|
dependency = Object.values(loaded).find(val => typeof val === 'function' && !!val.prototype && !!val.name);
|
|
59
55
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
const className = dependency.name;
|
|
66
|
-
const name = className.charAt(0).toLowerCase() + className.slice(1);
|
|
67
|
-
if (!this.checkRegistration(this.container, name)) {
|
|
56
|
+
if (typeof dependency === 'function' && !!dependency.prototype && !!dependency.name) {
|
|
57
|
+
if (this.registeredClasses.has(dependency))
|
|
58
|
+
continue;
|
|
59
|
+
const name = this.getName(dependency);
|
|
60
|
+
if (name && !this.checkRegistration(this.container, name)) {
|
|
68
61
|
this.container.register({
|
|
69
62
|
[name]: asClass(dependency).setLifetime(lifetime)
|
|
70
63
|
});
|
|
64
|
+
this.loadedPaths.add(normalizedMPath);
|
|
65
|
+
this.registeredClasses.add(dependency);
|
|
71
66
|
}
|
|
72
67
|
}
|
|
73
68
|
}
|
|
74
69
|
catch (err) {
|
|
75
70
|
if (verbose)
|
|
76
|
-
console.error(`[DI]
|
|
71
|
+
console.error(`[DI] Load Error:`, err.message);
|
|
77
72
|
}
|
|
78
73
|
}
|
|
79
74
|
return this;
|
|
80
75
|
}
|
|
81
76
|
register(Dependency, lifetime = Lifetime.SINGLETON) {
|
|
82
|
-
|
|
77
|
+
const name = this.getName(Dependency);
|
|
78
|
+
if (!name || this.registeredClasses.has(Dependency))
|
|
83
79
|
return this;
|
|
84
|
-
const name = Dependency.name.charAt(0).toLowerCase() + Dependency.name.slice(1);
|
|
85
80
|
if (this.checkRegistration(this.container, name))
|
|
86
81
|
return this;
|
|
87
82
|
this.container.register({ [name]: asClass(Dependency).setLifetime(lifetime) });
|
|
88
|
-
|
|
89
|
-
}
|
|
90
|
-
registerAll(dependencies, lifetime = Lifetime.SINGLETON) {
|
|
91
|
-
if (Array.isArray(dependencies))
|
|
92
|
-
dependencies.forEach(dep => this.register(dep, lifetime));
|
|
83
|
+
this.registeredClasses.add(Dependency);
|
|
93
84
|
return this;
|
|
94
85
|
}
|
|
95
86
|
registerInstance(name, instance) {
|
|
96
87
|
if (!name)
|
|
97
88
|
return this;
|
|
98
|
-
const formattedName =
|
|
99
|
-
if (this.checkRegistration(this.container, formattedName))
|
|
100
|
-
return this;
|
|
89
|
+
const formattedName = this.getName(name);
|
|
101
90
|
this.container.register({ [formattedName]: asValue(instance) });
|
|
102
91
|
return this;
|
|
103
92
|
}
|
|
104
93
|
async initialize(input, verbose = false) {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
const
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
if (this.initializedNames.has(key))
|
|
119
|
-
continue;
|
|
120
|
-
const reg = registrations[key];
|
|
121
|
-
if (!reg || reg.lifetime !== Lifetime.SINGLETON)
|
|
122
|
-
continue;
|
|
123
|
-
const instance = cradle[key];
|
|
124
|
-
if (instance && typeof instance.load === 'function') {
|
|
94
|
+
if (this.isInitializing)
|
|
95
|
+
return this;
|
|
96
|
+
this.isInitializing = true;
|
|
97
|
+
try {
|
|
98
|
+
const inputList = input ? (Array.isArray(input) ? input : [input]) : [];
|
|
99
|
+
// 1. ADIM: Senin verdiğin sıraya göre TEK TEK yükle (Senin için en önemli yer)
|
|
100
|
+
for (const item of inputList) {
|
|
101
|
+
const name = this.getName(item.service);
|
|
102
|
+
if (!name || this.initializedNames.has(name))
|
|
103
|
+
continue;
|
|
104
|
+
const reg = this.container.registrations[name];
|
|
105
|
+
if (!reg || reg.lifetime !== Lifetime.SINGLETON)
|
|
106
|
+
continue;
|
|
125
107
|
try {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
108
|
+
// Awilix instance'ı oluşturur (constructor çalışır)
|
|
109
|
+
const instance = this.container.cradle[name];
|
|
110
|
+
if (instance && typeof instance.load === 'function') {
|
|
111
|
+
// Burada await ediyoruz, yani bu servis bitmeden döngü ilerlemez
|
|
112
|
+
await instance.load(item.props || {});
|
|
113
|
+
}
|
|
114
|
+
this.initializedNames.add(name);
|
|
129
115
|
}
|
|
130
116
|
catch (err) {
|
|
131
117
|
if (verbose)
|
|
132
|
-
console.error(`[DI]
|
|
118
|
+
console.error(`[DI] Priority Init Failed (${name}):`, err.message);
|
|
133
119
|
}
|
|
134
120
|
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
if (instance && typeof shutdownMethod === 'function') {
|
|
121
|
+
// 2. ADIM: Listede olmayan ama register edilmiş diğer geri kalan singleton'ları yükle
|
|
122
|
+
const allKeys = Object.keys(this.container.registrations);
|
|
123
|
+
for (const key of allKeys) {
|
|
124
|
+
if (this.initializedNames.has(key))
|
|
125
|
+
continue;
|
|
126
|
+
const reg = this.container.registrations[key];
|
|
127
|
+
if (reg.lifetime !== Lifetime.SINGLETON)
|
|
128
|
+
continue;
|
|
144
129
|
try {
|
|
145
|
-
|
|
146
|
-
if (
|
|
147
|
-
|
|
130
|
+
const instance = this.container.cradle[key];
|
|
131
|
+
if (instance && typeof instance.load === 'function') {
|
|
132
|
+
await instance.load({});
|
|
133
|
+
}
|
|
134
|
+
this.initializedNames.add(key);
|
|
148
135
|
}
|
|
149
136
|
catch (err) {
|
|
150
|
-
|
|
137
|
+
if (verbose)
|
|
138
|
+
console.error(`[DI] Auto Init Failed (${key}):`, err.message);
|
|
151
139
|
}
|
|
152
140
|
}
|
|
153
141
|
}
|
|
154
|
-
|
|
142
|
+
finally {
|
|
143
|
+
this.isInitializing = false;
|
|
144
|
+
}
|
|
145
|
+
return this;
|
|
155
146
|
}
|
|
156
147
|
get(target) {
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
}
|
|
163
|
-
catch (err) {
|
|
164
|
-
if (err.message.includes('Cyclic dependencies')) {
|
|
165
|
-
console.error(`\n❌ [DI][CRITICAL] Cyclic dependency detected!\n🔍 Path: ${err.resolutionStack}`);
|
|
166
|
-
}
|
|
167
|
-
throw err;
|
|
168
|
-
}
|
|
148
|
+
const resolveName = this.getName(target);
|
|
149
|
+
return this.container.resolve(resolveName);
|
|
150
|
+
}
|
|
151
|
+
async shutdown() {
|
|
152
|
+
await this.container.dispose();
|
|
169
153
|
}
|
|
170
154
|
get cradle() { return this.container.cradle; }
|
|
171
155
|
}
|
|
172
|
-
|
|
156
|
+
const X_SYMBOL = Symbol.for('X');
|
|
157
|
+
const globalObj = global;
|
|
158
|
+
if (!globalObj[X_SYMBOL]) {
|
|
159
|
+
globalObj[X_SYMBOL] = new X();
|
|
160
|
+
}
|
|
161
|
+
export default globalObj[X_SYMBOL];
|