@vercube/di 0.0.21 → 0.0.23

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 (3) hide show
  1. package/README.md +10 -6
  2. package/dist/index.mjs +237 -241
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -3,10 +3,10 @@
3
3
  <br>
4
4
  <br>
5
5
 
6
- # Vercube
7
-
8
- Next generation HTTP framework
9
-
6
+ # Vercube
7
+
8
+ Next generation HTTP framework
9
+
10
10
  <a href="https://www.npmjs.com/package/@vercube/cli">
11
11
  <img src="https://img.shields.io/npm/v/%40vercube%2Fdi?style=for-the-badge&logo=npm&color=%23767eff" alt="npm"/>
12
12
  </a>
@@ -16,6 +16,9 @@
16
16
  <a href="https://github.com/vercube/vercube/blob/main/LICENSE" target="_blank">
17
17
  <img src="https://img.shields.io/npm/l/%40vercube%2Fdi?style=for-the-badge&color=%23767eff" alt="License"/>
18
18
  </a>
19
+ <a href="https://codecov.io/gh/vercube/vercube" target="_blank">
20
+ <img src="https://img.shields.io/codecov/c/github/vercube/vercube?style=for-the-badge&color=%23767eff" alt="Coverage"/>
21
+ </a>
19
22
  <br/>
20
23
  <br/>
21
24
  </div>
@@ -23,8 +26,9 @@
23
26
  An ultra-efficient JavaScript server framework that runs anywhere - Node.js, Bun, or Deno - with unmatched flexibility and complete configurability for developers who refuse to sacrifice speed or control.
24
27
 
25
28
  ## <a name="module">Dependencie Injection Module</a>
26
- The Dependency Injection (DI) module provides a powerful and flexible dependency injection system for Vercube applications. It enables loose coupling between components and makes your application more maintainable and testable.
27
29
 
30
+ The Dependency Injection (DI) module provides a powerful and flexible dependency injection system for Vercube applications. It enables loose coupling between components and makes your application more maintainable and testable.
28
31
 
29
32
  ## <a name="documentation">📖 Documentation</a>
30
- Comprehensive documentation is available at [vercube.dev](https://vercube.dev). There you'll find detailed module descriptions, project information, guides, and everything else you need to know about Vercube.
33
+
34
+ Comprehensive documentation is available at [vercube.dev](https://vercube.dev). There you'll find detailed module descriptions, project information, guides, and everything else you need to know about Vercube.
package/dist/index.mjs CHANGED
@@ -28,243 +28,6 @@ var BaseDecorator = class {
28
28
  destroyed() {}
29
29
  };
30
30
 
31
- //#endregion
32
- //#region src/Types/IOCTypes.ts
33
- let IOC;
34
- (function(_IOC) {
35
- let ServiceFactoryType = /* @__PURE__ */ function(ServiceFactoryType$1) {
36
- ServiceFactoryType$1["CLASS"] = "CLASS";
37
- ServiceFactoryType$1["CLASS_SINGLETON"] = "CLASS_SINGLETON";
38
- ServiceFactoryType$1["INSTANCE"] = "INSTANCE";
39
- return ServiceFactoryType$1;
40
- }({});
41
- _IOC.ServiceFactoryType = ServiceFactoryType;
42
- let InjectMethod = /* @__PURE__ */ function(InjectMethod$1) {
43
- InjectMethod$1["LAZY"] = "LAZY";
44
- InjectMethod$1["STATIC"] = "STATIC";
45
- return InjectMethod$1;
46
- }({});
47
- _IOC.InjectMethod = InjectMethod;
48
- let DependencyType = /* @__PURE__ */ function(DependencyType$1) {
49
- DependencyType$1[DependencyType$1["STANDARD"] = 0] = "STANDARD";
50
- DependencyType$1[DependencyType$1["OPTIONAL"] = 1] = "OPTIONAL";
51
- return DependencyType$1;
52
- }({});
53
- _IOC.DependencyType = DependencyType;
54
- })(IOC || (IOC = {}));
55
-
56
- //#endregion
57
- //#region src/Domain/Engine.ts
58
- /**
59
- * This map holds metadata for ALL classes in system along with their dependencies. Original idea was
60
- * to store those informations in object prototype, but accessing this map is blazing fast with Map
61
- * container (<1ms).
62
- */
63
- const classMap = /* @__PURE__ */ new Map();
64
- const ROOT_PROTO = Object.getPrototypeOf({});
65
- /**
66
- * This method registers @Inject() in particular class.
67
- * @param prototype class prototype for which we register @Inject()
68
- * @param propertyName name of property that is inejcted
69
- * @param dependency what we should inject there
70
- * @param type type of dependency (standard or optional dependency)
71
- */
72
- function registerInject(prototype, propertyName, dependency, type) {
73
- let entry = classMap.get(prototype);
74
- if (!entry) {
75
- const newEntry = { deps: [] };
76
- entry = newEntry;
77
- classMap.set(prototype, entry);
78
- }
79
- const newDep = {
80
- propertyName,
81
- dependency,
82
- type
83
- };
84
- entry.deps.push(newDep);
85
- }
86
- /**
87
- * Returns classmap entry for particular class. It holds information about @Injects for this particular class.
88
- * @param classType type of class to check
89
- * @returns class map entry or null if cannot be found
90
- */
91
- function getEntryForClass(classType) {
92
- const entry = classMap.get(classType.prototype);
93
- return entry === void 0 ? null : entry;
94
- }
95
- /**
96
- * Returns array of dependencies for particular class instance.
97
- * @param instance class instance
98
- * @returns array of @Inject dependencies defined for this class
99
- */
100
- function getDeps(instance) {
101
- const prototype = Object.getPrototypeOf(instance);
102
- if (!prototype) return [];
103
- const entry = classMap.get(prototype);
104
- return entry !== void 0 && entry.deps !== void 0 ? entry.deps : [];
105
- }
106
- /**
107
- * This method injects stuff into class, using container passed as first argument. We need container as
108
- * inject execution is always context based.
109
- * @param container container instance that is providing dependencies
110
- * @param instance class instance to inject
111
- * @param method inject method, "lazy" queries dep during property access while "static" injects during class creation
112
- */
113
- function injectDeps(container, instance, method) {
114
- let prototype = Object.getPrototypeOf(instance);
115
- if (!prototype) return;
116
- /**
117
- * Here we will traverse through prototype chain until we hit dead end (ROOT_PROTO). This is because we
118
- * must process inject for current class and also for every base class.
119
- *
120
- * So we will use "do" loop to iterate full prototype chain.
121
- */
122
- do {
123
- const entry = classMap.get(prototype);
124
- if (entry) for (const iter of entry.deps) {
125
- const propertyName = iter.propertyName;
126
- const dependency = iter.dependency;
127
- const type = iter.type;
128
- if (Object.prototype.hasOwnProperty.call(instance, propertyName) && instance[propertyName] !== void 0) continue;
129
- if (type === IOC.DependencyType.OPTIONAL) {
130
- Object.defineProperty(instance, propertyName, { get: function() {
131
- return container.getOptional(dependency);
132
- } });
133
- continue;
134
- }
135
- switch (method) {
136
- case IOC.InjectMethod.LAZY: {
137
- Object.defineProperty(instance, propertyName, { get: function() {
138
- return container.get(dependency);
139
- } });
140
- break;
141
- }
142
- case IOC.InjectMethod.STATIC: {
143
- instance[propertyName] = container.get(dependency);
144
- break;
145
- }
146
- default: throw new Error(`IOCEngine.injectDeps() - invalid inject method ${method}`);
147
- }
148
- }
149
- prototype = Object.getPrototypeOf(prototype);
150
- } while (prototype && prototype !== ROOT_PROTO);
151
- }
152
- const IOCEngine = {
153
- registerInject,
154
- getEntryForClass,
155
- injectDeps,
156
- getDeps
157
- };
158
-
159
- //#endregion
160
- //#region src/Decorators/Inject.ts
161
- /**
162
- * Injects a dependency with particular key to service.
163
- * @param key key to inject
164
- * @returns decorator
165
- */
166
- function Inject(key) {
167
- return (target, propertyName) => {
168
- IOCEngine.registerInject(target, propertyName, key, IOC.DependencyType.STANDARD);
169
- };
170
- }
171
-
172
- //#endregion
173
- //#region src/Decorators/InjectOptional.ts
174
- /**
175
- * Injects a dependency with particular key to service.
176
- * @param key key to inject
177
- * @returns decorator
178
- */
179
- function InjectOptional(key) {
180
- return (target, propertyName) => {
181
- IOCEngine.registerInject(target, propertyName, key, IOC.DependencyType.OPTIONAL);
182
- };
183
- }
184
-
185
- //#endregion
186
- //#region src/Decorators/Init.ts
187
- /**
188
- * This decorator fires the decorated function as soon as decorators are injected. You
189
- * can use this for initialization logic in runtime-loaded container deps.
190
- */
191
- var InitDecorator = class extends BaseDecorator {
192
- /**
193
- * Called when decorator is initialized.
194
- */
195
- created() {
196
- if (typeof this.instance[this.propertyName] === "function") this.instance[this.propertyName]();
197
- }
198
- };
199
- /**
200
- * Decorator that automatically executes the decorated method when dependencies are injected.
201
- * Use this decorator to run initialization logic for runtime-loaded container dependencies.
202
- * @returns {Function} Decorator function that creates an InitDecorator instance
203
- */
204
- function Init() {
205
- return createDecorator(InitDecorator, {});
206
- }
207
-
208
- //#endregion
209
- //#region src/Decorators/Destroy.ts
210
- /**
211
- * Decorator that handles cleanup tasks when a service or component is destroyed.
212
- * This decorator class extends BaseDecorator and executes the decorated method
213
- * during the destruction phase.
214
- */
215
- var DestroyDecorator = class extends BaseDecorator {
216
- /**
217
- * Called when decorator is destroyed. Executes the decorated method if it exists
218
- * as a function on the instance. Used for cleanup tasks like unregistering
219
- * listeners or clearing timers.
220
- */
221
- destroyed() {
222
- if (typeof this.instance[this.propertyName] === "function") this.instance[this.propertyName]();
223
- }
224
- };
225
- /**
226
- * Decorator that automatically executes the decorated method when the service or component
227
- * is destroyed. Use this decorator to run cleanup logic like unregistering event listeners
228
- * or clearing timers.
229
- *
230
- * @example
231
- * ```typescript
232
- * class MyService {
233
- * @Destroy()
234
- * cleanup() {
235
- * // Cleanup logic here
236
- * }
237
- * }
238
- * ```
239
- * @returns {Function} Decorator function that creates a DestroyDecorator instance
240
- */
241
- function Destroy() {
242
- return createDecorator(DestroyDecorator, {});
243
- }
244
-
245
- //#endregion
246
- //#region src/Domain/ContainerEvents.ts
247
- /**
248
- * This class allows for container to listen on various IOC events.
249
- */
250
- var ContainerEvents = class {
251
- fOnExpanded = [];
252
- /**
253
- * Registers to container "onExpanded" event.
254
- * @param handler event handler
255
- */
256
- onExpanded(handler) {
257
- this.fOnExpanded.push(handler);
258
- }
259
- /**
260
- * Calls on expanded event.
261
- * @param serviceKeys key of service we have installed
262
- */
263
- callOnExpanded(serviceKeys) {
264
- for (const handler of this.fOnExpanded) handler(serviceKeys);
265
- }
266
- };
267
-
268
31
  //#endregion
269
32
  //#region src/Utils/Utils.ts
270
33
  /**
@@ -368,6 +131,29 @@ function destroyContainer(container) {
368
131
  containerMap.delete(container);
369
132
  }
370
133
 
134
+ //#endregion
135
+ //#region src/Domain/ContainerEvents.ts
136
+ /**
137
+ * This class allows for container to listen on various IOC events.
138
+ */
139
+ var ContainerEvents = class {
140
+ fOnExpanded = [];
141
+ /**
142
+ * Registers to container "onExpanded" event.
143
+ * @param handler event handler
144
+ */
145
+ onExpanded(handler) {
146
+ this.fOnExpanded.push(handler);
147
+ }
148
+ /**
149
+ * Calls on expanded event.
150
+ * @param serviceKeys key of service we have installed
151
+ */
152
+ callOnExpanded(serviceKeys) {
153
+ for (const handler of this.fOnExpanded) handler(serviceKeys);
154
+ }
155
+ };
156
+
371
157
  //#endregion
372
158
  //#region src/Domain/Container.ts
373
159
  /**
@@ -604,7 +390,7 @@ var Container = class Container {
604
390
  internalResolve(serviceDef) {
605
391
  switch (serviceDef.type) {
606
392
  case IOC.ServiceFactoryType.INSTANCE: return serviceDef.serviceValue;
607
- case IOC.ServiceFactoryType.CLASS_SINGLETON: {
393
+ case IOC.ServiceFactoryType.CLASS_SINGLETON:
608
394
  if (!this.fSingletonInstances.has(serviceDef.serviceKey)) {
609
395
  const constructor = serviceDef.serviceValue;
610
396
  const instance = new constructor();
@@ -613,7 +399,6 @@ var Container = class Container {
613
399
  return instance;
614
400
  }
615
401
  return this.fSingletonInstances.get(serviceDef.serviceKey);
616
- }
617
402
  case IOC.ServiceFactoryType.CLASS: {
618
403
  const constructor = serviceDef.serviceValue;
619
404
  const instance = new constructor();
@@ -659,10 +444,9 @@ var Container = class Container {
659
444
  */
660
445
  internalDispose(def) {
661
446
  switch (def.type) {
662
- case IOC.ServiceFactoryType.INSTANCE: {
447
+ case IOC.ServiceFactoryType.INSTANCE:
663
448
  destroyDecorators(def.serviceValue, this);
664
449
  break;
665
- }
666
450
  case IOC.ServiceFactoryType.CLASS_SINGLETON: {
667
451
  const existingInstance = this.fSingletonInstances.get(def.serviceKey);
668
452
  if (existingInstance) {
@@ -688,5 +472,217 @@ var Container = class Container {
688
472
  }
689
473
  };
690
474
 
475
+ //#endregion
476
+ //#region src/Types/IOCTypes.ts
477
+ let IOC;
478
+ (function(_IOC) {
479
+ let ServiceFactoryType = /* @__PURE__ */ function(ServiceFactoryType$1) {
480
+ ServiceFactoryType$1["CLASS"] = "CLASS";
481
+ ServiceFactoryType$1["CLASS_SINGLETON"] = "CLASS_SINGLETON";
482
+ ServiceFactoryType$1["INSTANCE"] = "INSTANCE";
483
+ return ServiceFactoryType$1;
484
+ }({});
485
+ _IOC.ServiceFactoryType = ServiceFactoryType;
486
+ let InjectMethod = /* @__PURE__ */ function(InjectMethod$1) {
487
+ InjectMethod$1["LAZY"] = "LAZY";
488
+ InjectMethod$1["STATIC"] = "STATIC";
489
+ return InjectMethod$1;
490
+ }({});
491
+ _IOC.InjectMethod = InjectMethod;
492
+ let DependencyType = /* @__PURE__ */ function(DependencyType$1) {
493
+ DependencyType$1[DependencyType$1["STANDARD"] = 0] = "STANDARD";
494
+ DependencyType$1[DependencyType$1["OPTIONAL"] = 1] = "OPTIONAL";
495
+ return DependencyType$1;
496
+ }({});
497
+ _IOC.DependencyType = DependencyType;
498
+ })(IOC || (IOC = {}));
499
+
500
+ //#endregion
501
+ //#region src/Domain/Engine.ts
502
+ /**
503
+ * This map holds metadata for ALL classes in system along with their dependencies. Original idea was
504
+ * to store those informations in object prototype, but accessing this map is blazing fast with Map
505
+ * container (<1ms).
506
+ */
507
+ const classMap = /* @__PURE__ */ new Map();
508
+ const ROOT_PROTO = Object.getPrototypeOf({});
509
+ /**
510
+ * This method registers @Inject() in particular class.
511
+ * @param prototype class prototype for which we register @Inject()
512
+ * @param propertyName name of property that is inejcted
513
+ * @param dependency what we should inject there
514
+ * @param type type of dependency (standard or optional dependency)
515
+ */
516
+ function registerInject(prototype, propertyName, dependency, type) {
517
+ let entry = classMap.get(prototype);
518
+ if (!entry) {
519
+ const newEntry = { deps: [] };
520
+ entry = newEntry;
521
+ classMap.set(prototype, entry);
522
+ }
523
+ const newDep = {
524
+ propertyName,
525
+ dependency,
526
+ type
527
+ };
528
+ entry.deps.push(newDep);
529
+ }
530
+ /**
531
+ * Returns classmap entry for particular class. It holds information about @Injects for this particular class.
532
+ * @param classType type of class to check
533
+ * @returns class map entry or null if cannot be found
534
+ */
535
+ function getEntryForClass(classType) {
536
+ const entry = classMap.get(classType.prototype);
537
+ return entry === void 0 ? null : entry;
538
+ }
539
+ /**
540
+ * Returns array of dependencies for particular class instance.
541
+ * @param instance class instance
542
+ * @returns array of @Inject dependencies defined for this class
543
+ */
544
+ function getDeps(instance) {
545
+ const prototype = Object.getPrototypeOf(instance);
546
+ if (!prototype) return [];
547
+ const entry = classMap.get(prototype);
548
+ return entry !== void 0 && entry.deps !== void 0 ? entry.deps : [];
549
+ }
550
+ /**
551
+ * This method injects stuff into class, using container passed as first argument. We need container as
552
+ * inject execution is always context based.
553
+ * @param container container instance that is providing dependencies
554
+ * @param instance class instance to inject
555
+ * @param method inject method, "lazy" queries dep during property access while "static" injects during class creation
556
+ */
557
+ function injectDeps(container, instance, method) {
558
+ let prototype = Object.getPrototypeOf(instance);
559
+ if (!prototype) return;
560
+ /**
561
+ * Here we will traverse through prototype chain until we hit dead end (ROOT_PROTO). This is because we
562
+ * must process inject for current class and also for every base class.
563
+ *
564
+ * So we will use "do" loop to iterate full prototype chain.
565
+ */
566
+ do {
567
+ const entry = classMap.get(prototype);
568
+ if (entry) for (const iter of entry.deps) {
569
+ const propertyName = iter.propertyName;
570
+ const dependency = iter.dependency;
571
+ const type = iter.type;
572
+ if (Object.prototype.hasOwnProperty.call(instance, propertyName) && instance[propertyName] !== void 0) continue;
573
+ if (type === IOC.DependencyType.OPTIONAL) {
574
+ Object.defineProperty(instance, propertyName, { get: function() {
575
+ return container.getOptional(dependency);
576
+ } });
577
+ continue;
578
+ }
579
+ switch (method) {
580
+ case IOC.InjectMethod.LAZY:
581
+ Object.defineProperty(instance, propertyName, { get: function() {
582
+ return container.get(dependency);
583
+ } });
584
+ break;
585
+ case IOC.InjectMethod.STATIC:
586
+ instance[propertyName] = container.get(dependency);
587
+ break;
588
+ default: throw new Error(`IOCEngine.injectDeps() - invalid inject method ${method}`);
589
+ }
590
+ }
591
+ prototype = Object.getPrototypeOf(prototype);
592
+ } while (prototype && prototype !== ROOT_PROTO);
593
+ }
594
+ const IOCEngine = {
595
+ registerInject,
596
+ getEntryForClass,
597
+ injectDeps,
598
+ getDeps
599
+ };
600
+
601
+ //#endregion
602
+ //#region src/Decorators/Inject.ts
603
+ /**
604
+ * Injects a dependency with particular key to service.
605
+ * @param key key to inject
606
+ * @returns decorator
607
+ */
608
+ function Inject(key) {
609
+ return (target, propertyName) => {
610
+ IOCEngine.registerInject(target, propertyName, key, IOC.DependencyType.STANDARD);
611
+ };
612
+ }
613
+
614
+ //#endregion
615
+ //#region src/Decorators/InjectOptional.ts
616
+ /**
617
+ * Injects a dependency with particular key to service.
618
+ * @param key key to inject
619
+ * @returns decorator
620
+ */
621
+ function InjectOptional(key) {
622
+ return (target, propertyName) => {
623
+ IOCEngine.registerInject(target, propertyName, key, IOC.DependencyType.OPTIONAL);
624
+ };
625
+ }
626
+
627
+ //#endregion
628
+ //#region src/Decorators/Init.ts
629
+ /**
630
+ * This decorator fires the decorated function as soon as decorators are injected. You
631
+ * can use this for initialization logic in runtime-loaded container deps.
632
+ */
633
+ var InitDecorator = class extends BaseDecorator {
634
+ /**
635
+ * Called when decorator is initialized.
636
+ */
637
+ created() {
638
+ if (typeof this.instance[this.propertyName] === "function") this.instance[this.propertyName]();
639
+ }
640
+ };
641
+ /**
642
+ * Decorator that automatically executes the decorated method when dependencies are injected.
643
+ * Use this decorator to run initialization logic for runtime-loaded container dependencies.
644
+ * @returns {Function} Decorator function that creates an InitDecorator instance
645
+ */
646
+ function Init() {
647
+ return createDecorator(InitDecorator, {});
648
+ }
649
+
650
+ //#endregion
651
+ //#region src/Decorators/Destroy.ts
652
+ /**
653
+ * Decorator that handles cleanup tasks when a service or component is destroyed.
654
+ * This decorator class extends BaseDecorator and executes the decorated method
655
+ * during the destruction phase.
656
+ */
657
+ var DestroyDecorator = class extends BaseDecorator {
658
+ /**
659
+ * Called when decorator is destroyed. Executes the decorated method if it exists
660
+ * as a function on the instance. Used for cleanup tasks like unregistering
661
+ * listeners or clearing timers.
662
+ */
663
+ destroyed() {
664
+ if (typeof this.instance[this.propertyName] === "function") this.instance[this.propertyName]();
665
+ }
666
+ };
667
+ /**
668
+ * Decorator that automatically executes the decorated method when the service or component
669
+ * is destroyed. Use this decorator to run cleanup logic like unregistering event listeners
670
+ * or clearing timers.
671
+ *
672
+ * @example
673
+ * ```typescript
674
+ * class MyService {
675
+ * @Destroy()
676
+ * cleanup() {
677
+ * // Cleanup logic here
678
+ * }
679
+ * }
680
+ * ```
681
+ * @returns {Function} Decorator function that creates a DestroyDecorator instance
682
+ */
683
+ function Destroy() {
684
+ return createDecorator(DestroyDecorator, {});
685
+ }
686
+
691
687
  //#endregion
692
688
  export { BaseDecorator, Container, Destroy, IOC, Identity, Init, Inject, InjectOptional, createDecorator, destroyContainer, destroyDecorators, initializeContainer, initializeDecorators };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vercube/di",
3
- "version": "0.0.21",
3
+ "version": "0.0.23",
4
4
  "description": "Dependencie Injection module for Vercube framework",
5
5
  "repository": {
6
6
  "type": "git",