@lppedd/di-wise-neo 0.3.1 → 0.3.2

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 CHANGED
@@ -2,7 +2,13 @@
2
2
  <div align="center">
3
3
  <h1>di-wise-neo</h1>
4
4
  <p>Lightweight, type-safe, flexible dependency injection library for TypeScript and JavaScript</p>
5
- <img src="./.github/images/neo-wall.jpg" title="di-wise-neo" alt="di-wise-neo" style="border: 3px solid black; border-radius: 15px;" />
5
+
6
+ [![test](https://img.shields.io/github/actions/workflow/status/lppedd/di-wise-neo/test.yml.svg?branch=main)](https://github.com/lppedd/di-wise-neo/actions/workflows/test.yml)
7
+ [![npm](https://img.shields.io/npm/v/@lppedd/di-wise-neo?color=%23de1f1f&logo=npm)](https://www.npmjs.com/package/@lppedd/di-wise-neo)
8
+ [![npm gzipped size](https://img.shields.io/bundlejs/size/@lppedd/di-wise-neo)](https://bundlejs.com/?q=@lppedd/di-wise-neo)
9
+ [![license](https://img.shields.io/github/license/lppedd/di-wise-neo?color=blue)](https://github.com/lppedd/di-wise-neo/blob/main/LICENSE)
10
+
11
+ <img src="./.github/images/neo-wall.jpg" alt="di-wise-neo" style="border: 3px solid black; border-radius: 15px;" />
6
12
  <div><sub>yes, I like The Matrix</sub></div>
7
13
  </div>
8
14
 
@@ -16,12 +22,14 @@
16
22
 
17
23
  - [Why yet another library](#why-yet-another-library)
18
24
  - [Installation](#installation)
25
+ - [API reference](#api-reference)
19
26
  - [Ergonomics](#ergonomics)
20
27
  - [Quickstart](#quickstart)
21
28
  - [Container scopes](#container-scopes)
22
29
  - [Token registration](#token-registration)
23
30
  - [Function-based injection](#function-based-injection)
24
31
  - [Decorator-based injection](#decorator-based-injection)
32
+ - [Behavioral decorators](#behavioral-decorators)
25
33
  - [Testing support](#testing-support)
26
34
 
27
35
  ## Why yet another library
@@ -75,7 +83,7 @@ production needs.
75
83
  ## Installation
76
84
 
77
85
  ```sh
78
- npm install @lppedd/di-wise-neo
86
+ npm i @lppedd/di-wise-neo
79
87
  ```
80
88
 
81
89
  ```sh
@@ -85,6 +93,9 @@ pnpm add @lppedd/di-wise-neo
85
93
  ```sh
86
94
  yarn add @lppedd/di-wise-neo
87
95
  ```
96
+ ## API reference
97
+
98
+ You can find the complete API reference at https://lppedd.github.io/di-wise-neo
88
99
 
89
100
  ## Ergonomics
90
101
 
@@ -139,7 +150,7 @@ const container = createContainer({
139
150
  defaultScope: Scope.Container,
140
151
  });
141
152
 
142
- // Register our managed dependencies into the container
153
+ // Register our managed dependencies in the container
143
154
  container.register(ExtensionContext)
144
155
  .register(SecretStore)
145
156
  .register(ContributionRegistrar);
@@ -209,7 +220,7 @@ Alternatively, use an explicit `ClassProvider` object - useful when registering
209
220
  an interface or abstract type:
210
221
 
211
222
  ```ts
212
- const Store = Type<Store>("Store");
223
+ const Store = createType<Store>("Store");
213
224
  container.register(Store, {
214
225
  useClass: SecretStore, // class SecretStore implements Store
215
226
  });
@@ -223,7 +234,7 @@ caching it according to the configured scope.
223
234
  A lazily computed value can be registered using a factory function:
224
235
 
225
236
  ```ts
226
- const Env = Type<string>("Env")
237
+ const Env = createType<string>("Env")
227
238
  container.register(Env, {
228
239
  useFactory: () => isNode() ? "Node.js" : "browser",
229
240
  });
@@ -237,7 +248,7 @@ according to the configured scope.
237
248
  A static value - always taken as-is and unaffected by scopes - can be registered using:
238
249
 
239
250
  ```ts
240
- const PID = Type<number>("PID");
251
+ const PID = createType<number>("PID");
241
252
  const processId = spawnProcess();
242
253
  container.register(PID, {
243
254
  useValue: processId,
@@ -253,7 +264,7 @@ Registers an alias to another token, allowing multiple identifiers to resolve to
253
264
  Using the previous `PID` example, we can register a `TaskID` alias:
254
265
 
255
266
  ```ts
256
- const TaskID = Type<number>("TaskID");
267
+ const TaskID = createType<number>("TaskID");
257
268
  container.register(TaskID, {
258
269
  useExisting: PID,
259
270
  });
@@ -424,10 +435,55 @@ export class ExtensionContext {
424
435
  }
425
436
  ```
426
437
 
438
+ ## Behavioral decorators
439
+
440
+ The library includes two behavioral decorators that influence how classes are registered in the container.
441
+ These decorators attach metadata to the class type, which is then interpreted by the container during registration.
442
+
443
+ ### `@Scoped`
444
+
445
+ Specifies a default scope for the decorated class:
446
+
447
+ ```ts
448
+ @Scoped(Scope.Container)
449
+ export class ExtensionContext {
450
+ /* ... */
451
+ }
452
+ ```
453
+
454
+ Applying `@Scoped(Scope.Container)` to the `ExtensionContext` class instructs the DI container
455
+ to register it with the **Container** scope by default.
456
+
457
+ This default can be overridden by explicitly providing registration options:
458
+
459
+ ```ts
460
+ container.register(
461
+ ExtensionContext,
462
+ { useClass: ExtensionContext },
463
+ { scope: Scope.Resolution },
464
+ );
465
+ ```
466
+
467
+ In this example, `ExtensionContext` will be registered with **Resolution** scope instead.
468
+
469
+ ### `@AutoRegister`
470
+
471
+ Enables automatic registration of the decorated class if it has not been registered explicitly.
472
+
473
+ ```ts
474
+ @AutoRegister()
475
+ export class ExtensionContext {
476
+ /* ... */
477
+ }
478
+
479
+ // Resolve the class without prior registration. It works!
480
+ container.resolve(ExtensionContext);
481
+ ```
482
+
427
483
  ## Testing support
428
484
 
429
485
  Testing is an important part of software development, and dependency injection is meant to make it easier.
430
- The **di-wise-neo** container API exposes methods to more easily integrate with testing scenarios.
486
+ The container API exposes methods to more easily integrate with testing scenarios.
431
487
 
432
488
  ### `resetRegistry`
433
489
 
@@ -1,19 +1,3 @@
1
- /**
2
- * Constructor type.
3
- */
4
- interface Constructor<Instance extends object> {
5
- new (...args: any[]): Instance;
6
- readonly name: string;
7
- readonly length: number;
8
- }
9
- /**
10
- * Token type.
11
- */
12
- type Token<Value = any> = [Value] extends [object] ? Type<Value> | Constructor<Value> : Type<Value>;
13
- /**
14
- * Describes a {@link Token} array with at least one element.
15
- */
16
- type Tokens<Value = any> = [Token<Value>, ...Token<Value>[]];
17
1
  /**
18
2
  * Type API.
19
3
  */
@@ -27,8 +11,8 @@ interface Type<A> {
27
11
  *
28
12
  * @example
29
13
  * ```ts
30
- * const A = Type<A>("A");
31
- * const B = Type<B>("B");
14
+ * const A = createType<A>("A");
15
+ * const B = createType<B>("B");
32
16
  *
33
17
  * A.inter("I", B); // => Type<A & B>
34
18
  * ```
@@ -39,25 +23,41 @@ interface Type<A> {
39
23
  *
40
24
  * @example
41
25
  * ```ts
42
- * const A = Type<A>("A");
43
- * const B = Type<B>("B");
26
+ * const A = createType<A>("A");
27
+ * const B = createType<B>("B");
44
28
  *
45
29
  * A.union("U", B); // => Type<A | B>
46
30
  * ```
47
31
  */
48
32
  union<B>(typeName: string, B: Type<B>): Type<A | B>;
49
33
  }
34
+ /**
35
+ * Constructor type.
36
+ */
37
+ interface Constructor<Instance extends object> {
38
+ new (...args: any[]): Instance;
39
+ readonly name: string;
40
+ readonly length: number;
41
+ }
42
+ /**
43
+ * Token type.
44
+ */
45
+ type Token<Value = any> = [Value] extends [object] ? Type<Value> | Constructor<Value> : Type<Value>;
46
+ /**
47
+ * Describes a {@link Token} array with at least one element.
48
+ */
49
+ type Tokens<Value = any> = [Token<Value>, ...Token<Value>[]];
50
50
  /**
51
51
  * Create a type token.
52
52
  *
53
53
  * @example
54
54
  * ```ts
55
- * const Spell = Type<Spell>("Spell");
55
+ * const Spell = createType<Spell>("Spell");
56
56
  * ```
57
57
  *
58
58
  * @__NO_SIDE_EFFECTS__
59
59
  */
60
- declare function Type<T>(typeName: string): Type<T>;
60
+ declare function createType<T>(typeName: string): Type<T>;
61
61
 
62
62
  /**
63
63
  * Provides a class instance for a token via a class constructor.
@@ -115,7 +115,7 @@ interface RegistrationOptions {
115
115
  * ```ts
116
116
  * class Wizard {
117
117
  * wand = inject(
118
- * Build(() => {
118
+ * build(() => {
119
119
  * const wand = inject(Wand);
120
120
  * wand.owner = this;
121
121
  * // ...
@@ -127,7 +127,7 @@ interface RegistrationOptions {
127
127
  *
128
128
  * @__NO_SIDE_EFFECTS__
129
129
  */
130
- declare function Build<Value>(factory: (...args: []) => Value): Type<Value>;
130
+ declare function build<Value>(factory: (...args: []) => Value): Type<Value>;
131
131
 
132
132
  /**
133
133
  * Container creation options.
@@ -768,5 +768,5 @@ interface Middleware {
768
768
  */
769
769
  declare function applyMiddleware(container: Container, middlewares: Middleware[]): Container;
770
770
 
771
- export { AutoRegister, Build, Inject, InjectAll, Injectable, Injector, Optional, OptionalAll, Scope, Scoped, Type, applyMiddleware, createContainer, forwardRef, inject, injectAll, injectBy };
772
- export type { ClassProvider, Constructor, Container, ContainerOptions, ExistingProvider, FactoryProvider, Middleware, MiddlewareComposer, Provider, RegistrationOptions, Token, TokenRef, Tokens, TokensRef, ValueProvider };
771
+ export { AutoRegister, Inject, InjectAll, Injectable, Injector, Optional, OptionalAll, Scope, Scoped, applyMiddleware, build, createContainer, createType, forwardRef, inject, injectAll, injectBy };
772
+ export type { ClassProvider, Constructor, Container, ContainerOptions, ExistingProvider, FactoryProvider, Middleware, MiddlewareComposer, Provider, RegistrationOptions, Token, TokenRef, Tokens, TokensRef, Type, ValueProvider };
package/dist/cjs/index.js CHANGED
@@ -235,15 +235,15 @@ const Scope = {
235
235
  *
236
236
  * @example
237
237
  * ```ts
238
- * const Spell = Type<Spell>("Spell");
238
+ * const Spell = createType<Spell>("Spell");
239
239
  * ```
240
240
  *
241
241
  * @__NO_SIDE_EFFECTS__
242
- */ function Type(typeName) {
242
+ */ function createType(typeName) {
243
243
  const type = {
244
244
  name: `Type<${typeName}>`,
245
- inter: Type,
246
- union: Type,
245
+ inter: createType,
246
+ union: createType,
247
247
  toString () {
248
248
  return type.name;
249
249
  }
@@ -349,7 +349,7 @@ function isBuilder(provider) {
349
349
  * ```ts
350
350
  * class Wizard {
351
351
  * wand = inject(
352
- * Build(() => {
352
+ * build(() => {
353
353
  * const wand = inject(Wand);
354
354
  * wand.owner = this;
355
355
  * // ...
@@ -360,8 +360,8 @@ function isBuilder(provider) {
360
360
  * ```
361
361
  *
362
362
  * @__NO_SIDE_EFFECTS__
363
- */ function Build(factory) {
364
- const token = Type(`Build<${getTypeName(factory)}>`);
363
+ */ function build(factory) {
364
+ const token = createType(`Build<${getTypeName(factory)}>`);
365
365
  const provider = {
366
366
  useFactory: factory
367
367
  };
@@ -961,7 +961,7 @@ function OptionalAll(token) {
961
961
  * const wizard = container.resolve(Wizard);
962
962
  * wizard.getWand(); // => Wand
963
963
  * ```
964
- */ const Injector = /*@__PURE__*/ Build(function Injector() {
964
+ */ const Injector = /*@__PURE__*/ build(function Injector() {
965
965
  const context = ensureInjectionContext(Injector);
966
966
  const resolution = context.resolution;
967
967
  const dependentFrame = resolution.stack.peek();
@@ -1036,7 +1036,6 @@ function OptionalAll(token) {
1036
1036
  }
1037
1037
 
1038
1038
  exports.AutoRegister = AutoRegister;
1039
- exports.Build = Build;
1040
1039
  exports.Inject = Inject;
1041
1040
  exports.InjectAll = InjectAll;
1042
1041
  exports.Injectable = Injectable;
@@ -1045,9 +1044,10 @@ exports.Optional = Optional;
1045
1044
  exports.OptionalAll = OptionalAll;
1046
1045
  exports.Scope = Scope;
1047
1046
  exports.Scoped = Scoped;
1048
- exports.Type = Type;
1049
1047
  exports.applyMiddleware = applyMiddleware;
1048
+ exports.build = build;
1050
1049
  exports.createContainer = createContainer;
1050
+ exports.createType = createType;
1051
1051
  exports.forwardRef = forwardRef;
1052
1052
  exports.inject = inject;
1053
1053
  exports.injectAll = injectAll;