@lppedd/di-wise-neo 0.21.1 → 0.23.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.
@@ -29,7 +29,7 @@ interface RegistrationOptions {
29
29
  /**
30
30
  * The scope of the registration.
31
31
  */
32
- readonly scope?: Scope;
32
+ readonly scope?: Scope | undefined;
33
33
  }
34
34
  /**
35
35
  * Create a one-off type token from a factory function.
@@ -82,7 +82,7 @@ interface ProviderType<T> extends Type<T> {
82
82
  /**
83
83
  * The type's default registration options.
84
84
  */
85
- readonly options?: RegistrationOptions;
85
+ readonly options?: RegistrationOptions | undefined;
86
86
  }
87
87
  /**
88
88
  * Constructor type.
@@ -168,7 +168,7 @@ interface ClassProvider<Instance extends object> {
168
168
  * }
169
169
  * ```
170
170
  */
171
- readonly name?: string;
171
+ readonly name?: string | undefined;
172
172
  }
173
173
  /**
174
174
  * Provides a value for a token via a factory function.
@@ -196,7 +196,7 @@ interface FactoryProvider<Value> {
196
196
  * }
197
197
  * ```
198
198
  */
199
- readonly name?: string;
199
+ readonly name?: string | undefined;
200
200
  }
201
201
  /**
202
202
  * Provides a static - already constructed - value for a token.
@@ -221,7 +221,7 @@ interface ValueProvider<Value> {
221
221
  * }
222
222
  * ```
223
223
  */
224
- readonly name?: string;
224
+ readonly name?: string | undefined;
225
225
  }
226
226
  /**
227
227
  * Aliases another registered token.
@@ -244,7 +244,7 @@ interface ExistingProvider<Value> {
244
244
  * });
245
245
  * ```
246
246
  */
247
- readonly useExisting: Token<Value> | [Token<Value>, string?];
247
+ readonly useExisting: Token<Value> | [Token<Value>, (string | undefined)?];
248
248
  /**
249
249
  * An optional name to qualify this provider.
250
250
  * If specified, the token must be resolved using the same name.
@@ -260,13 +260,19 @@ interface ExistingProvider<Value> {
260
260
  * }
261
261
  * ```
262
262
  */
263
- readonly name?: string;
263
+ readonly name?: string | undefined;
264
264
  }
265
265
  /**
266
266
  * A token provider.
267
267
  */
268
268
  type Provider<Value> = ClassProvider<Value & object> | FactoryProvider<Value> | ValueProvider<Value> | ExistingProvider<Value>;
269
269
 
270
+ type RequiredNonNullable<T> = {
271
+ [P in keyof T]-?: NonNullable<T[P]>;
272
+ };
273
+
274
+ type ProviderFor<V> = V extends object ? Provider<V> : Exclude<Provider<V>, ClassProvider<any>>;
275
+ type RegistrationOptionsFor<P> = P extends ValueProvider<any> ? never : RegistrationOptions;
270
276
  /**
271
277
  * Container creation options.
272
278
  */
@@ -276,20 +282,20 @@ interface ContainerOptions {
276
282
  *
277
283
  * @defaultValue Transient
278
284
  */
279
- readonly defaultScope: Scope;
285
+ readonly defaultScope?: Scope | undefined;
280
286
  /**
281
287
  * Whether to automatically register an unregistered class when resolving it as a token.
282
288
  *
283
289
  * @defaultValue false
284
290
  */
285
- readonly autoRegister: boolean;
291
+ readonly autoRegister?: boolean | undefined;
286
292
  /**
287
293
  * Whether to also dispose values provided via {@link ValueProvider}, which are not
288
294
  * created or managed by the container, when the container itself is disposed.
289
295
  *
290
296
  * @defaultValue false
291
297
  */
292
- readonly disposeUnmanaged: boolean;
298
+ readonly disposeUnmanaged?: boolean | undefined;
293
299
  }
294
300
  /**
295
301
  * Child container creation options.
@@ -300,7 +306,7 @@ interface ChildContainerOptions extends ContainerOptions {
300
306
  *
301
307
  * @defaultValue true
302
308
  */
303
- readonly copyHooks: boolean;
309
+ readonly copyHooks?: boolean | undefined;
304
310
  }
305
311
  /**
306
312
  * A hook into the lifecycle of a {@link Container}.
@@ -316,14 +322,14 @@ interface ContainerHook {
316
322
  * @param value - The provided value.
317
323
  * @param scope - The {@link Scope} of the provided value.
318
324
  */
319
- readonly onProvide?: (value: unknown, scope: Scope) => void;
325
+ readonly onProvide?: ((value: unknown, scope: Scope) => void) | undefined;
320
326
  /**
321
327
  * Called after the container has been disposed.
322
328
  *
323
329
  * @param values - All distinct values that were cached by the disposed container.
324
330
  * Currently, only **Container**-scoped token values are cached.
325
331
  */
326
- readonly onDispose?: (values: unknown[]) => void;
332
+ readonly onDispose?: ((values: unknown[]) => void) | undefined;
327
333
  }
328
334
  /**
329
335
  * A Dependency Injection container.
@@ -332,7 +338,7 @@ interface Container {
332
338
  /**
333
339
  * The options used to create this container.
334
340
  */
335
- readonly options: ContainerOptions;
341
+ readonly options: RequiredNonNullable<ContainerOptions>;
336
342
  /**
337
343
  * The parent container, or `undefined` if this is the root container.
338
344
  */
@@ -346,7 +352,7 @@ interface Container {
346
352
  *
347
353
  * You can pass specific options to override the inherited ones.
348
354
  */
349
- createChild(options?: Partial<ChildContainerOptions>): Container;
355
+ createChild(options?: ChildContainerOptions): Container;
350
356
  /**
351
357
  * Clears and returns all distinct values cached by this container.
352
358
  * Values from {@link ValueProvider} registrations are not included, as they are never cached.
@@ -406,6 +412,23 @@ interface Container {
406
412
  * Registers a token type with a default {@link Provider} and optional default registration options.
407
413
  */
408
414
  register<Value>(token: ProviderType<Value>): Container;
415
+ /**
416
+ * Registers a {@link Provider} with a token or class.
417
+ *
418
+ * The provider must be one of:
419
+ * - {@link ClassProvider} via `useClass`
420
+ * - {@link FactoryProvider} via `useFactory`
421
+ * - {@link ValueProvider} via `useValue`
422
+ * - {@link ExistingProvider} via `useExisting`
423
+ *
424
+ * For {@link ClassProvider} registrations, the default scope is determined by the {@link Scoped}
425
+ * decorator applied to the provided class - if present - or by the {@link ContainerOptions.defaultScope}
426
+ * value, but it can be overridden by passing explicit registration options.
427
+ *
428
+ * For {@link ValueProvider} registrations, the provided value is returned as-is and never cached,
429
+ * and registration options do not apply.
430
+ */
431
+ register<Value, ProviderValue extends Value, Provider extends ProviderFor<ProviderValue>>(token: Token<Value>, provider: ProviderFor<ProviderValue> & Provider, options?: RegistrationOptionsFor<Provider>): Container;
409
432
  /**
410
433
  * Registers a {@link ClassProvider} with a token.
411
434
  *
@@ -638,7 +661,7 @@ interface Container {
638
661
  /**
639
662
  * Creates a new container.
640
663
  */
641
- declare function createContainer(options?: Partial<ContainerOptions>): Container;
664
+ declare function createContainer(options?: ContainerOptions): Container;
642
665
 
643
666
  /**
644
667
  * Class decorator that enables auto-registration of an unregistered class
@@ -659,8 +682,10 @@ declare function AutoRegister<This extends object>(): ClassDecorator<This>;
659
682
  * Class decorator that sets the class scope to **Container** and enables
660
683
  * eager instantiation when the class is registered in the container.
661
684
  *
662
- * This causes the container to immediately create and cache the instance of the class,
663
- * instead of deferring instantiation until the first resolution.
685
+ * This causes the container to create and cache the instance of the class
686
+ * immediately, instead of deferring it until the first resolution.
687
+ *
688
+ * If the class cannot be resolved at registration time, registration fails.
664
689
  *
665
690
  * Example:
666
691
  * ```ts
@@ -668,7 +693,7 @@ declare function AutoRegister<This extends object>(): ClassDecorator<This>;
668
693
  * class Wizard {}
669
694
  *
670
695
  * // Wizard is registered with Container scope, and an instance
671
- * // is immediately created and cached by the container
696
+ * // is created and cached immediately by the container
672
697
  * container.register(Wizard);
673
698
  * ```
674
699
  */
@@ -679,8 +704,9 @@ declare function EagerInstantiate<This extends object>(): ClassDecorator<This>;
679
704
  *
680
705
  * Throws an error if:
681
706
  * - The class is not registered in the container.
682
- * - A circular dependency is detected. Use function injection with {@link injectBy}
683
- * if resolving circular dependencies is necessary.
707
+ * - A circular dependency is detected.
708
+ *
709
+ * Use {@link injectBy} when you need to resolve circular dependencies.
684
710
  */
685
711
  declare function Inject<Instance extends object>(Class: Constructor<Instance>): ParameterDecorator;
686
712
  /**
@@ -688,8 +714,9 @@ declare function Inject<Instance extends object>(Class: Constructor<Instance>):
688
714
  *
689
715
  * Throws an error if:
690
716
  * - The token is not registered in the container.
691
- * - A circular dependency is detected. Use function injection with {@link injectBy}
692
- * if resolving circular dependencies is necessary.
717
+ * - A circular dependency is detected.
718
+ *
719
+ * Use {@link injectBy} when you need to resolve circular dependencies.
693
720
  */
694
721
  declare function Inject<Value>(token: Token<Value>): ParameterDecorator;
695
722
  /**
@@ -700,8 +727,9 @@ declare function Inject<Value>(token: Token<Value>): ParameterDecorator;
700
727
  *
701
728
  * Throws an error if:
702
729
  * - The token is not registered in the container.
703
- * - A circular dependency is detected. Use function injection with {@link injectBy}
704
- * if resolving circular dependencies is necessary.
730
+ * - A circular dependency is detected.
731
+ *
732
+ * Use function injection with {@link injectBy} when you need to resolve circular dependencies.
705
733
  *
706
734
  * Example:
707
735
  * ```ts
@@ -810,17 +838,18 @@ declare function InjectAll<Value>(token: Token<Value>): ParameterDecorator;
810
838
  declare function InjectAll<Value>(tokens: TokenRef<Value>): ParameterDecorator;
811
839
 
812
840
  /**
813
- * Qualifies a class or an injected parameter with a unique name.
841
+ * Qualifies a class or an injected parameter with a name.
842
+ *
843
+ * On a class, the name is used when registering that class with the container.
844
+ * On a parameter, the name selects a named registration or alias during injection.
814
845
  *
815
- * This allows the container to distinguish between multiple implementations
816
- * of the same interface or type during registration and injection.
846
+ * This is useful when multiple registrations exist for the same token.
817
847
  *
818
848
  * Example:
819
849
  * ```ts
820
850
  * @Named("dumbledore")
821
851
  * class Dumbledore implements Wizard {}
822
852
  *
823
- * // Register Dumbledore with Type<Wizard>
824
853
  * container.register(IWizard, { useClass: Dumbledore });
825
854
  * const dumbledore = container.resolve(IWizard, "dumbledore");
826
855
  * ```
@@ -832,7 +861,7 @@ declare function Named<This extends object>(name: string): ClassDecorator<This>
832
861
  * or `undefined` if the class is not registered in the container.
833
862
  *
834
863
  * Throws an error if a circular dependency is detected. Use function injection
835
- * with {@link optionalBy} if resolving circular dependencies is necessary.
864
+ * with {@link optionalBy} when you need to resolve circular dependencies.
836
865
  */
837
866
  declare function Optional<Instance extends object>(Class: Constructor<Instance>): ParameterDecorator;
838
867
  /**
@@ -840,7 +869,7 @@ declare function Optional<Instance extends object>(Class: Constructor<Instance>)
840
869
  * or `undefined` if the token is not registered in the container.
841
870
  *
842
871
  * Throws an error if a circular dependency is detected. Use function injection
843
- * with {@link optionalBy} if resolving circular dependencies is necessary.
872
+ * with {@link optionalBy} when you need to resolve circular dependencies.
844
873
  */
845
874
  declare function Optional<Value>(token: Token<Value>): ParameterDecorator;
846
875
  /**
@@ -851,7 +880,7 @@ declare function Optional<Value>(token: Token<Value>): ParameterDecorator;
851
880
  * the {@link tokenRef} helper function.
852
881
  *
853
882
  * Throws an error if a circular dependency is detected. Use function injection
854
- * with {@link optionalBy} if resolving circular dependencies is necessary.
883
+ * with {@link optionalBy} when you need to resolve circular dependencies.
855
884
  *
856
885
  * Example:
857
886
  * ```ts
@@ -901,6 +930,50 @@ declare function OptionalAll<Value>(token: Token<Value>): ParameterDecorator;
901
930
  */
902
931
  declare function OptionalAll<Value>(tokens: TokenRef<Value>): ParameterDecorator;
903
932
 
933
+ /**
934
+ * Class decorator that registers the decorated type with the **Container** scope.
935
+ *
936
+ * Use this scope when you want one cached instance per container,
937
+ * with parent-container lookup fallback.
938
+ *
939
+ * Example:
940
+ * ```ts
941
+ * @ContainerScoped()
942
+ * class Wizard {
943
+ * // ...
944
+ * }
945
+ * ```
946
+ */
947
+ declare function ContainerScoped<This extends object>(): ClassDecorator<This>;
948
+ /**
949
+ * Class decorator that registers the decorated type with the **Resolution** scope.
950
+ *
951
+ * Use this scope when you want one cached instance per resolution graph,
952
+ * so repeated resolutions within the same request reuse the same value.
953
+ *
954
+ * Example:
955
+ * ```ts
956
+ * @ResolutionScoped()
957
+ * class Wand {
958
+ * // ...
959
+ * }
960
+ * ```
961
+ */
962
+ declare function ResolutionScoped<This extends object>(): ClassDecorator<This>;
963
+ /**
964
+ * Class decorator that registers the decorated type with the **Transient** scope.
965
+ *
966
+ * Use this scope when you want a fresh instance every time the class is resolved.
967
+ *
968
+ * Example:
969
+ * ```ts
970
+ * @TransientScoped()
971
+ * class Wand {
972
+ * // ...
973
+ * }
974
+ * ```
975
+ */
976
+ declare function TransientScoped<This extends object>(): ClassDecorator<This>;
904
977
  /**
905
978
  * Class decorator for setting the scope of the decorated type when registering it.
906
979
  *
@@ -1139,7 +1212,7 @@ declare function setClassIdentityMapping<T extends object>(transformedClass: Con
1139
1212
  * or `undefined` if the class is not registered in the container.
1140
1213
  *
1141
1214
  * Throws an error if a circular dependency is detected.
1142
- * Use {@link optionalBy} if resolving circular dependencies is necessary.
1215
+ * Use {@link optionalBy} when you need to resolve circular dependencies.
1143
1216
  */
1144
1217
  declare function optional<Instance extends object>(Class: Constructor<Instance>, name?: string): Instance | undefined;
1145
1218
  /**
@@ -1147,7 +1220,7 @@ declare function optional<Instance extends object>(Class: Constructor<Instance>,
1147
1220
  * or `undefined` if the token is not registered in the container.
1148
1221
  *
1149
1222
  * Throws an error if a circular dependency is detected.
1150
- * Use {@link optionalBy} if resolving circular dependencies is necessary.
1223
+ * Use {@link optionalBy} when you need to resolve circular dependencies.
1151
1224
  */
1152
1225
  declare function optional<Value>(token: Token<Value>, name?: string): Value | undefined;
1153
1226
 
@@ -1191,5 +1264,5 @@ declare function optionalBy<Instance extends object>(thisArg: any, Class: Constr
1191
1264
  */
1192
1265
  declare function optionalBy<Value>(thisArg: any, token: Token<Value>, name?: string): Value | undefined;
1193
1266
 
1194
- export { AutoRegister, EagerInstantiate, Inject, InjectAll, Injectable, Injector, Named, Optional, OptionalAll, Scope, Scoped, assertInjectionContext, build, classRef, createContainer, createType, inject, injectAll, injectBy, optional, optionalAll, optionalBy, setClassIdentityMapping, tokenRef };
1267
+ export { AutoRegister, ContainerScoped, EagerInstantiate, Inject, InjectAll, Injectable, Injector, Named, Optional, OptionalAll, ResolutionScoped, Scope, Scoped, TransientScoped, assertInjectionContext, build, classRef, createContainer, createType, inject, injectAll, injectBy, optional, optionalAll, optionalBy, setClassIdentityMapping, tokenRef };
1195
1268
  export type { ChildContainerOptions, ClassProvider, ClassRef, Constructor, Container, ContainerHook, ContainerOptions, ExistingProvider, FactoryProvider, Provider, ProviderType, RegistrationOptions, Token, TokenRef, Tokens, Type, ValueProvider };
package/dist/cjs/index.js CHANGED
@@ -1,6 +1,5 @@
1
1
  Object.defineProperty(exports, '__esModule', { value: true });
2
2
 
3
- // @internal
4
3
  function check(condition, message) {
5
4
  if (!condition) {
6
5
  throw new Error(tag(typeof message === "string" ? message : message()));
@@ -260,10 +259,7 @@ class Metadata {
260
259
  methods: new Map()
261
260
  };
262
261
  this.tokenRef = {
263
- // prettier-ignore
264
- getRefToken: ()=>{
265
- check(false, "internal: unexpected getRefToken call");
266
- },
262
+ getRefToken: ()=>check(false, "internal: unexpected getRefToken call"),
267
263
  getRefTokens: ()=>new Set()
268
264
  };
269
265
  this.provider = {
@@ -445,14 +441,13 @@ function describeParam(target, methodKey, parameterIndex) {
445
441
  // @__NO_SIDE_EFFECTS__
446
442
  function createType(typeName, provider, options) {
447
443
  const name = `Type<${typeName}>`;
448
- const decorator = (target, propertyKey, parameterIndex)=>{
444
+ const type = (target, propertyKey, parameterIndex)=>{
449
445
  updateParameterMetadata(name, target, propertyKey, parameterIndex, (dependency)=>{
450
446
  checkSingleDecorator(dependency, target, propertyKey, parameterIndex);
451
447
  dependency.appliedBy = "Inject";
452
- dependency.tokenRef = tokenRef(()=>decorator);
448
+ dependency.tokenRef = tokenRef(()=>type);
453
449
  });
454
450
  };
455
- const type = decorator;
456
451
  Object.defineProperty(type, "name", {
457
452
  value: name
458
453
  });
@@ -645,7 +640,7 @@ function isDisposable(value) {
645
640
  defaultScope: options?.defaultScope ?? this.myOptions.defaultScope,
646
641
  autoRegister: options?.autoRegister ?? this.myOptions.autoRegister,
647
642
  disposeUnmanaged: options?.disposeUnmanaged ?? this.myOptions.disposeUnmanaged,
648
- copyHooks: options?.copyHooks
643
+ copyHooks: options?.copyHooks ?? true
649
644
  });
650
645
  this.myChildren.add(container);
651
646
  return container;
@@ -1132,7 +1127,7 @@ function isDisposable(value) {
1132
1127
  * ```
1133
1128
  */ // @__NO_SIDE_EFFECTS__
1134
1129
  function AutoRegister() {
1135
- return function(Class) {
1130
+ return (Class)=>{
1136
1131
  const metadata = getMetadata(Class);
1137
1132
  metadata.autoRegister = true;
1138
1133
  };
@@ -1142,8 +1137,10 @@ function AutoRegister() {
1142
1137
  * Class decorator that sets the class scope to **Container** and enables
1143
1138
  * eager instantiation when the class is registered in the container.
1144
1139
  *
1145
- * This causes the container to immediately create and cache the instance of the class,
1146
- * instead of deferring instantiation until the first resolution.
1140
+ * This causes the container to create and cache the instance of the class
1141
+ * immediately, instead of deferring it until the first resolution.
1142
+ *
1143
+ * If the class cannot be resolved at registration time, registration fails.
1147
1144
  *
1148
1145
  * Example:
1149
1146
  * ```ts
@@ -1151,18 +1148,19 @@ function AutoRegister() {
1151
1148
  * class Wizard {}
1152
1149
  *
1153
1150
  * // Wizard is registered with Container scope, and an instance
1154
- * // is immediately created and cached by the container
1151
+ * // is created and cached immediately by the container
1155
1152
  * container.register(Wizard);
1156
1153
  * ```
1157
1154
  */ // @__NO_SIDE_EFFECTS__
1158
1155
  function EagerInstantiate() {
1159
- return function(Class) {
1156
+ return (Class)=>{
1160
1157
  const metadata = getMetadata(Class);
1161
1158
  const currentScope = metadata.scope;
1162
1159
  check(!currentScope || currentScope.value === "Container", ()=>{
1163
1160
  const { value, appliedBy } = currentScope;
1161
+ const by = appliedBy === "Scoped" ? `${appliedBy}(${value})` : appliedBy;
1164
1162
  const className = getTokenName(Class);
1165
- return `class ${className}: scope ${value} was already set by @${appliedBy},\n ` + `but @EagerInstantiate is trying to set a conflicting scope Container.\n ` + `Only one decorator should set the class scope, or all must agree on the same value.`;
1163
+ return `class ${className}: scope ${value} was already set by @${by},\n ` + `but @EagerInstantiate is trying to set a conflicting scope Container.\n ` + `Only one decorator should set the class scope, or all must use the same value.`;
1166
1164
  });
1167
1165
  metadata.eagerInstantiate = true;
1168
1166
  metadata.scope = {
@@ -1174,7 +1172,7 @@ function EagerInstantiate() {
1174
1172
 
1175
1173
  // @__NO_SIDE_EFFECTS__
1176
1174
  function Inject(token) {
1177
- return function(target, propertyKey, parameterIndex) {
1175
+ return (target, propertyKey, parameterIndex)=>{
1178
1176
  updateParameterMetadata("Inject", target, propertyKey, parameterIndex, (dependency)=>{
1179
1177
  checkSingleDecorator(dependency, target, propertyKey, parameterIndex);
1180
1178
  dependency.appliedBy = "Inject";
@@ -1185,7 +1183,7 @@ function Inject(token) {
1185
1183
 
1186
1184
  // @__NO_SIDE_EFFECTS__
1187
1185
  function Injectable(...args) {
1188
- return function(Class) {
1186
+ return (Class)=>{
1189
1187
  const metadata = getMetadata(Class);
1190
1188
  const arg0 = args[0];
1191
1189
  const ref = isTokenRef(arg0) ? arg0 : tokenRef(()=>args);
@@ -1205,7 +1203,7 @@ function Injectable(...args) {
1205
1203
 
1206
1204
  // @__NO_SIDE_EFFECTS__
1207
1205
  function InjectAll(token) {
1208
- return function(target, propertyKey, parameterIndex) {
1206
+ return (target, propertyKey, parameterIndex)=>{
1209
1207
  updateParameterMetadata("InjectAll", target, propertyKey, parameterIndex, (dependency)=>{
1210
1208
  checkSingleDecorator(dependency, target, propertyKey, parameterIndex);
1211
1209
  dependency.appliedBy = "InjectAll";
@@ -1216,24 +1214,25 @@ function InjectAll(token) {
1216
1214
  }
1217
1215
 
1218
1216
  /**
1219
- * Qualifies a class or an injected parameter with a unique name.
1217
+ * Qualifies a class or an injected parameter with a name.
1220
1218
  *
1221
- * This allows the container to distinguish between multiple implementations
1222
- * of the same interface or type during registration and injection.
1219
+ * On a class, the name is used when registering that class with the container.
1220
+ * On a parameter, the name selects a named registration or alias during injection.
1221
+ *
1222
+ * This is useful when multiple registrations exist for the same token.
1223
1223
  *
1224
1224
  * Example:
1225
1225
  * ```ts
1226
1226
  * @Named("dumbledore")
1227
1227
  * class Dumbledore implements Wizard {}
1228
1228
  *
1229
- * // Register Dumbledore with Type<Wizard>
1230
1229
  * container.register(IWizard, { useClass: Dumbledore });
1231
1230
  * const dumbledore = container.resolve(IWizard, "dumbledore");
1232
1231
  * ```
1233
1232
  */ // @__NO_SIDE_EFFECTS__
1234
1233
  function Named(name) {
1235
1234
  check(name.trim(), "@Named qualifier must not be empty");
1236
- return function(target, propertyKey, parameterIndex) {
1235
+ return (target, propertyKey, parameterIndex)=>{
1237
1236
  if (parameterIndex === undefined) {
1238
1237
  // The decorator has been applied to the class
1239
1238
  const Class = target;
@@ -1257,7 +1256,7 @@ function Named(name) {
1257
1256
 
1258
1257
  // @__NO_SIDE_EFFECTS__
1259
1258
  function Optional(token) {
1260
- return function(target, propertyKey, parameterIndex) {
1259
+ return (target, propertyKey, parameterIndex)=>{
1261
1260
  updateParameterMetadata("Optional", target, propertyKey, parameterIndex, (dependency)=>{
1262
1261
  checkSingleDecorator(dependency, target, propertyKey, parameterIndex);
1263
1262
  dependency.appliedBy = "Optional";
@@ -1268,7 +1267,7 @@ function Optional(token) {
1268
1267
 
1269
1268
  // @__NO_SIDE_EFFECTS__
1270
1269
  function OptionalAll(token) {
1271
- return function(target, propertyKey, parameterIndex) {
1270
+ return (target, propertyKey, parameterIndex)=>{
1272
1271
  updateParameterMetadata("OptionalAll", target, propertyKey, parameterIndex, (dependency)=>{
1273
1272
  checkSingleDecorator(dependency, target, propertyKey, parameterIndex);
1274
1273
  dependency.appliedBy = "OptionalAll";
@@ -1278,6 +1277,56 @@ function OptionalAll(token) {
1278
1277
  };
1279
1278
  }
1280
1279
 
1280
+ /**
1281
+ * Class decorator that registers the decorated type with the **Container** scope.
1282
+ *
1283
+ * Use this scope when you want one cached instance per container,
1284
+ * with parent-container lookup fallback.
1285
+ *
1286
+ * Example:
1287
+ * ```ts
1288
+ * @ContainerScoped()
1289
+ * class Wizard {
1290
+ * // ...
1291
+ * }
1292
+ * ```
1293
+ */ // @__NO_SIDE_EFFECTS__
1294
+ function ContainerScoped() {
1295
+ return scoped("Container", "ContainerScoped");
1296
+ }
1297
+ /**
1298
+ * Class decorator that registers the decorated type with the **Resolution** scope.
1299
+ *
1300
+ * Use this scope when you want one cached instance per resolution graph,
1301
+ * so repeated resolutions within the same request reuse the same value.
1302
+ *
1303
+ * Example:
1304
+ * ```ts
1305
+ * @ResolutionScoped()
1306
+ * class Wand {
1307
+ * // ...
1308
+ * }
1309
+ * ```
1310
+ */ // @__NO_SIDE_EFFECTS__
1311
+ function ResolutionScoped() {
1312
+ return scoped("Resolution", "ResolutionScoped");
1313
+ }
1314
+ /**
1315
+ * Class decorator that registers the decorated type with the **Transient** scope.
1316
+ *
1317
+ * Use this scope when you want a fresh instance every time the class is resolved.
1318
+ *
1319
+ * Example:
1320
+ * ```ts
1321
+ * @TransientScoped()
1322
+ * class Wand {
1323
+ * // ...
1324
+ * }
1325
+ * ```
1326
+ */ // @__NO_SIDE_EFFECTS__
1327
+ function TransientScoped() {
1328
+ return scoped("Transient", "TransientScoped");
1329
+ }
1281
1330
  /**
1282
1331
  * Class decorator for setting the scope of the decorated type when registering it.
1283
1332
  *
@@ -1299,18 +1348,21 @@ function OptionalAll(token) {
1299
1348
  * ```
1300
1349
  */ // @__NO_SIDE_EFFECTS__
1301
1350
  function Scoped(scope) {
1302
- return function(Class) {
1351
+ return scoped(scope, "Scoped");
1352
+ }
1353
+ function scoped(scope, decorator) {
1354
+ return (Class)=>{
1303
1355
  const metadata = getMetadata(Class);
1304
1356
  const currentScope = metadata.scope;
1305
1357
  check(!currentScope || currentScope.value === scope, ()=>{
1306
1358
  const { value, appliedBy } = currentScope;
1307
- const by = appliedBy === "Scoped" ? `another @${appliedBy} decorator` : `@${appliedBy}`;
1359
+ const by = appliedBy === "Scoped" ? `${appliedBy}(${value})` : appliedBy;
1308
1360
  const className = getTokenName(Class);
1309
- return `class ${className}: scope ${value} was already set by ${by},\n ` + `but @Scoped is trying to set a conflicting scope ${scope}.\n ` + `Only one decorator should set the class scope, or all must agree on the same value.`;
1361
+ return `class ${className}: scope ${value} was already set by @${by},\n ` + `but @${decorator} is trying to set a conflicting scope ${scope}.\n ` + `Only one decorator should set the class scope, or all must use the same value.`;
1310
1362
  });
1311
1363
  metadata.scope = {
1312
1364
  value: scope,
1313
- appliedBy: "Scoped"
1365
+ appliedBy: decorator
1314
1366
  };
1315
1367
  };
1316
1368
  }
@@ -1374,6 +1426,7 @@ const Scope = {
1374
1426
  };
1375
1427
 
1376
1428
  exports.AutoRegister = AutoRegister;
1429
+ exports.ContainerScoped = ContainerScoped;
1377
1430
  exports.EagerInstantiate = EagerInstantiate;
1378
1431
  exports.Inject = Inject;
1379
1432
  exports.InjectAll = InjectAll;
@@ -1382,8 +1435,10 @@ exports.Injector = Injector;
1382
1435
  exports.Named = Named;
1383
1436
  exports.Optional = Optional;
1384
1437
  exports.OptionalAll = OptionalAll;
1438
+ exports.ResolutionScoped = ResolutionScoped;
1385
1439
  exports.Scope = Scope;
1386
1440
  exports.Scoped = Scoped;
1441
+ exports.TransientScoped = TransientScoped;
1387
1442
  exports.assertInjectionContext = assertInjectionContext;
1388
1443
  exports.build = build;
1389
1444
  exports.classRef = classRef;