@xrystal/core 3.20.9 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "author": "Yusuf Yasir KAYGUSUZ",
3
3
  "name": "@xrystal/core",
4
- "version": "3.20.9",
4
+ "version": "3.21.0",
5
5
  "description": "Project core for xrystal",
6
6
  "publishConfig": {
7
7
  "access": "public",
@@ -26,26 +26,9 @@ export declare const getControllerCtx: () => {
26
26
  _isRaw?: boolean;
27
27
  };
28
28
  };
29
- export declare const protocol: (callback: () => Promise<any>, protocol?: ProtocolEnum) => Promise<any>;
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
- protected systemService: SystemService;
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 { Controller };
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, x } from '../../utils/index';
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 const protocol = async (callback, protocol = ProtocolEnum.HTTP) => {
7
- const store = controllerContextStorage.getStore();
8
- if (store) {
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.tmp.configs.loaders.controller.protocols;
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.winston.log({
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 };
@@ -43,10 +43,10 @@ export default class LoggerService {
43
43
  constructor({ systemService, configsService }) {
44
44
  this.#systemService = systemService;
45
45
  this.#configsService = configsService;
46
- this.serviceName = this.#systemService?.tmp?.configs?.service;
47
- this.kafkaLogsTopic = this.#configsService?.all?.kafkaLogsTopic;
48
46
  }
49
47
  load = async () => {
48
+ this.serviceName = this.#systemService?.tmp?.configs?.service;
49
+ this.kafkaLogsTopic = this.#configsService?.all?.kafkaLogsTopic;
50
50
  winston.addColors(customColors);
51
51
  this.winston = winston.createLogger({
52
52
  level: this.#configsService?.all?.systemLoggerLayer || 'info',
@@ -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 } = {
@@ -11,6 +11,7 @@ declare class X extends XHelper {
11
11
  private registeredClasses;
12
12
  private isInitializing;
13
13
  constructor();
14
+ private getName;
14
15
  load(patterns: string | string[], options?: {
15
16
  verbose?: boolean;
16
17
  exclude?: string | Function | (string | Function)[];
@@ -19,10 +19,16 @@ class X extends XHelper {
19
19
  strict: true
20
20
  });
21
21
  }
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 '';
28
+ }
22
29
  async load(patterns, options = {}) {
23
30
  const { verbose = false, exclude = [], lifetime = Lifetime.SINGLETON } = options;
24
31
  const cwd = process.cwd();
25
- const excludeList = Array.isArray(exclude) ? exclude : [exclude];
26
32
  const resolvedPatterns = (Array.isArray(patterns) ? patterns : [patterns]).map(p => {
27
33
  const resolved = path.isAbsolute(p) ? p : path.resolve(cwd, p);
28
34
  return resolved.replace(/\\/g, '/').toLowerCase();
@@ -50,10 +56,10 @@ class X extends XHelper {
50
56
  if (typeof dependency === 'function' && !!dependency.prototype && !!dependency.name) {
51
57
  if (this.registeredClasses.has(dependency))
52
58
  continue;
53
- const name = dependency.name.charAt(0).toLowerCase() + dependency.name.slice(1);
54
- if (!this.checkRegistration(this.container, name)) {
59
+ const name = this.getName(dependency);
60
+ if (name && !this.checkRegistration(this.container, name)) {
55
61
  this.container.register({
56
- [name]: asClass(dependency).singleton()
62
+ [name]: asClass(dependency).setLifetime(lifetime)
57
63
  });
58
64
  this.loadedPaths.add(normalizedMPath);
59
65
  this.registeredClasses.add(dependency);
@@ -68,19 +74,19 @@ class X extends XHelper {
68
74
  return this;
69
75
  }
70
76
  register(Dependency, lifetime = Lifetime.SINGLETON) {
71
- if (!Dependency?.name || this.registeredClasses.has(Dependency))
77
+ const name = this.getName(Dependency);
78
+ if (!name || this.registeredClasses.has(Dependency))
72
79
  return this;
73
- const name = Dependency.name.charAt(0).toLowerCase() + Dependency.name.slice(1);
74
80
  if (this.checkRegistration(this.container, name))
75
81
  return this;
76
- this.container.register({ [name]: asClass(Dependency).singleton() });
82
+ this.container.register({ [name]: asClass(Dependency).setLifetime(lifetime) });
77
83
  this.registeredClasses.add(Dependency);
78
84
  return this;
79
85
  }
80
86
  registerInstance(name, instance) {
81
87
  if (!name)
82
88
  return this;
83
- const formattedName = name.charAt(0).toLowerCase() + name.slice(1);
89
+ const formattedName = this.getName(name);
84
90
  this.container.register({ [formattedName]: asValue(instance) });
85
91
  return this;
86
92
  }
@@ -89,34 +95,47 @@ class X extends XHelper {
89
95
  return this;
90
96
  this.isInitializing = true;
91
97
  try {
92
- const cradle = this.container.cradle;
93
98
  const inputList = input ? (Array.isArray(input) ? input : [input]) : [];
94
- const propsMap = new Map();
99
+ // 1. ADIM: Senin verdiğin sıraya göre TEK TEK yükle (Senin için en önemli yer)
95
100
  for (const item of inputList) {
96
- if (!item?.service)
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)
97
106
  continue;
98
- const name = typeof item.service === 'function' ? item.service.name.charAt(0).toLowerCase() + item.service.name.slice(1) : item.service;
99
- if (name)
100
- propsMap.set(name, item.props);
107
+ try {
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);
115
+ }
116
+ catch (err) {
117
+ if (verbose)
118
+ console.error(`[DI] Priority Init Failed (${name}):`, err.message);
119
+ }
101
120
  }
102
- const keys = Object.keys(this.container.registrations);
103
- for (const key of keys) {
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) {
104
124
  if (this.initializedNames.has(key))
105
125
  continue;
106
126
  const reg = this.container.registrations[key];
107
127
  if (reg.lifetime !== Lifetime.SINGLETON)
108
128
  continue;
109
129
  try {
110
- const instance = cradle[key];
130
+ const instance = this.container.cradle[key];
111
131
  if (instance && typeof instance.load === 'function') {
112
- const props = propsMap.get(key) || {};
113
- await instance.load(props);
132
+ await instance.load({});
114
133
  }
115
134
  this.initializedNames.add(key);
116
135
  }
117
136
  catch (err) {
118
137
  if (verbose)
119
- console.error(`[DI] Init Failed (${key}):`, err.message);
138
+ console.error(`[DI] Auto Init Failed (${key}):`, err.message);
120
139
  }
121
140
  }
122
141
  }
@@ -126,9 +145,7 @@ class X extends XHelper {
126
145
  return this;
127
146
  }
128
147
  get(target) {
129
- const resolveName = typeof target === 'function'
130
- ? target.name.charAt(0).toLowerCase() + target.name.slice(1)
131
- : target;
148
+ const resolveName = this.getName(target);
132
149
  return this.container.resolve(resolveName);
133
150
  }
134
151
  async shutdown() {