@xrystal/core 3.13.6 → 3.14.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.13.6",
4
+ "version": "3.14.0",
5
5
  "description": "Project core for xrystal",
6
6
  "publishConfig": {
7
7
  "access": "public",
@@ -19,7 +19,11 @@ const coreLoader = async ({}) => {
19
19
  x
20
20
  .load([
21
21
  path.join(__dirname, '..', 'loader', '**/*.{ts,js}'),
22
- ], false)
22
+ ], {
23
+ exclude: [
24
+ path.join(__dirname, '..', 'utils', '**/class.x.{ts,js}'),
25
+ ]
26
+ })
23
27
  .initialize([
24
28
  {
25
29
  service: SystemService,
@@ -2,11 +2,14 @@ export declare class X {
2
2
  private container;
3
3
  private initializedNames;
4
4
  constructor();
5
- load(patterns: string | string[], verbose?: boolean): this;
5
+ private getSource;
6
+ load(patterns: string | string[], options?: {
7
+ verbose?: boolean;
8
+ exclude?: string | Function | (string | Function)[];
9
+ }): this;
6
10
  register(Dependency: any): this;
7
11
  registerAll(dependencies: any[]): this;
8
12
  registerInstance(name: string, instance: any): this;
9
- remove(target: string | any): this;
10
13
  initialize(input?: {
11
14
  service: any;
12
15
  props?: any;
@@ -9,13 +9,16 @@ export class X {
9
9
  strict: true
10
10
  });
11
11
  }
12
- load(patterns, verbose = false) {
13
- if (!patterns || (Array.isArray(patterns) && patterns.length === 0))
14
- return this;
12
+ getSource(filePath) {
13
+ const projectRoot = process.cwd().replace(/\\/g, '/');
14
+ const normalizedPath = filePath.replace(/\\/g, '/');
15
+ return normalizedPath.includes('node_modules') || !normalizedPath.startsWith(projectRoot) ? 'LIB' : 'APP';
16
+ }
17
+ load(patterns, options = {}) {
18
+ const { verbose = false, exclude = [] } = options;
15
19
  const cwd = process.cwd();
16
- const resolvedPatterns = (Array.isArray(patterns) ? patterns : [patterns])
17
- .filter(p => typeof p === 'string')
18
- .map(p => {
20
+ const excludeList = Array.isArray(exclude) ? exclude : [exclude];
21
+ const resolvedPatterns = (Array.isArray(patterns) ? patterns : [patterns]).map(p => {
19
22
  const resolved = path.isAbsolute(p) ? p : path.resolve(cwd, p);
20
23
  return resolved.replace(/\\/g, '/');
21
24
  });
@@ -24,10 +27,11 @@ export class X {
24
27
  modules = listModules(resolvedPatterns);
25
28
  }
26
29
  catch (err) {
27
- console.error(`[DI] Critical: Path resolution failed: ${err.message}`);
30
+ console.error(`[DI][CRITICAL] Path resolution failed: ${err.message}`);
28
31
  return this;
29
32
  }
30
33
  for (const m of modules) {
34
+ const source = this.getSource(m.path);
31
35
  if (m.path === __filename || m.path.endsWith('.d.ts') || m.path.endsWith('.map'))
32
36
  continue;
33
37
  try {
@@ -36,6 +40,20 @@ export class X {
36
40
  if (!dependency) {
37
41
  dependency = Object.values(loaded).find(val => typeof val === 'function' && !!val.prototype && !!val.name);
38
42
  }
43
+ const isExcluded = excludeList.some(ex => {
44
+ if (typeof ex === 'string') {
45
+ return m.path.includes(ex) || m.name === ex;
46
+ }
47
+ if (typeof ex === 'function') {
48
+ return dependency === ex;
49
+ }
50
+ return false;
51
+ });
52
+ if (isExcluded) {
53
+ if (verbose)
54
+ console.log(`[DI][${source}] Excluded: ${m.name}`);
55
+ continue;
56
+ }
39
57
  const isClass = typeof dependency === 'function' && !!dependency.prototype && !!dependency.name;
40
58
  if (isClass) {
41
59
  const className = dependency.name;
@@ -43,12 +61,12 @@ export class X {
43
61
  if (!this.isRegistered(name)) {
44
62
  this.container.register({ [name]: asClass(dependency).singleton() });
45
63
  if (verbose)
46
- console.log(`[DI] Registered: ${name}`);
64
+ console.log(`[DI][${source}] Registered: ${name}`);
47
65
  }
48
66
  }
49
67
  }
50
68
  catch (err) {
51
- console.error(`[DI] Critical: Failed to load module at ${m.path}:`, err.message);
69
+ console.error(`[DI][${source}] Load Error in ${m.name}:`, err.message);
52
70
  }
53
71
  }
54
72
  return this;
@@ -63,9 +81,8 @@ export class X {
63
81
  return this;
64
82
  }
65
83
  registerAll(dependencies) {
66
- if (!Array.isArray(dependencies))
67
- return this;
68
- dependencies.forEach(dep => this.register(dep));
84
+ if (Array.isArray(dependencies))
85
+ dependencies.forEach(dep => this.register(dep));
69
86
  return this;
70
87
  }
71
88
  registerInstance(name, instance) {
@@ -77,65 +94,48 @@ export class X {
77
94
  this.container.register({ [formattedName]: asValue(instance) });
78
95
  return this;
79
96
  }
80
- remove(target) {
81
- const name = typeof target === 'function'
82
- ? target.name.charAt(0).toLowerCase() + target.name.slice(1)
83
- : target;
84
- this.container.register(name, asValue(undefined));
85
- this.initializedNames.delete(name);
86
- return this;
87
- }
88
97
  async initialize(input, verbose = false) {
89
98
  const cradle = this.container.cradle;
90
99
  const inputList = input ? (Array.isArray(input) ? input : [input]) : [];
100
+ const propsMap = new Map();
91
101
  for (const item of inputList) {
92
102
  if (!item?.service)
93
103
  continue;
94
- const name = typeof item.service === 'function'
95
- ? item.service.name.charAt(0).toLowerCase() + item.service.name.slice(1)
96
- : item.service;
97
- if (this.initializedNames.has(name))
98
- continue;
99
- const instance = cradle[name];
100
- if (instance) {
101
- if (typeof instance.load === 'function') {
102
- try {
103
- await instance.load(item.props || {});
104
- if (verbose)
105
- console.log(`[DI] Initialized (Priority): ${name}`);
106
- }
107
- catch (err) {
108
- console.error(`[DI] Critical: Priority service "${name}" failed:`, err.message);
109
- }
110
- }
111
- this.initializedNames.add(name);
112
- }
104
+ const name = typeof item.service === 'function' ? item.service.name.charAt(0).toLowerCase() + item.service.name.slice(1) : item.service;
105
+ if (name)
106
+ propsMap.set(name, item.props);
113
107
  }
114
- for (const key of Object.keys(this.container.registrations)) {
108
+ const registrationKeys = Object.keys(this.container.registrations);
109
+ const allKeys = new Set([...propsMap.keys(), ...registrationKeys]);
110
+ for (const key of allKeys) {
115
111
  if (this.initializedNames.has(key))
116
112
  continue;
117
113
  const instance = cradle[key];
118
114
  if (instance && typeof instance.load === 'function') {
115
+ const source = instance.constructor && instance.constructor.name ? 'APP' : 'LIB';
119
116
  try {
120
- await instance.load({});
117
+ const props = propsMap.get(key) || {};
118
+ await instance.load(props);
119
+ this.initializedNames.add(key);
121
120
  if (verbose)
122
- console.log(`[DI] Initialized (Auto): ${key}`);
121
+ console.log(`[DI][${source}] Initialized: ${key}`);
123
122
  }
124
123
  catch (err) {
125
- console.error(`[DI] Critical: Auto service "${key}" failed:`, err.message);
124
+ console.error(`[DI][${source}] Initialization Failed: ${key} ->`, err.message);
126
125
  }
127
126
  }
128
- this.initializedNames.add(key);
129
127
  }
130
128
  return this;
131
129
  }
132
130
  get(target) {
133
- if (!target)
134
- throw new Error('[DI] Target is required');
135
- const resolveName = typeof target === 'function'
136
- ? target.name.charAt(0).toLowerCase() + target.name.slice(1)
137
- : target;
138
- return this.container.resolve(resolveName);
131
+ try {
132
+ const resolveName = typeof target === 'function' ? target.name.charAt(0).toLowerCase() + target.name.slice(1) : target;
133
+ return this.container.resolve(resolveName);
134
+ }
135
+ catch (err) {
136
+ console.error(`[DI][ERROR] Resolution Failed:`, err.message);
137
+ throw err;
138
+ }
139
139
  }
140
140
  get cradle() { return this.container.cradle; }
141
141
  isRegistered(name) {