static-injector 2.1.1 → 2.2.1

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 (96) hide show
  1. package/import/commonjs/index.js +127 -197
  2. package/import/{es2015 → es2022}/di/create_injector.js +0 -2
  3. package/import/{es2015 → es2022}/di/forward_ref.js +29 -2
  4. package/import/{es2015 → es2022}/di/injection_token.js +5 -3
  5. package/import/{es2015 → es2022}/di/injector.js +15 -16
  6. package/import/{es2015 → es2022}/di/injector_compatibility.js +8 -3
  7. package/import/{es2015 → es2022}/di/interface/defs.js +2 -16
  8. package/import/{es2015 → es2022}/di/interface/injector.js +1 -1
  9. package/import/es2022/di/provider_collection.js +104 -0
  10. package/import/{es2015 → es2022}/di/r3_injector.js +46 -15
  11. package/import/{es2015 → es2022}/errors.js +4 -2
  12. package/import/{es2015 → es2022}/render3/error_code.js +1 -0
  13. package/import/es2022/render3/fields.js +22 -0
  14. package/import/{fesm2015 → fesm2022}/index.js +127 -198
  15. package/import/typings/di/create_injector.d.ts +3 -5
  16. package/import/typings/di/forward_ref.d.ts +29 -2
  17. package/import/typings/di/inject_switch.d.ts +1 -1
  18. package/import/typings/di/injection_token.d.ts +1 -1
  19. package/import/typings/di/injector.d.ts +3 -3
  20. package/import/typings/di/injector_compatibility.d.ts +1 -0
  21. package/import/typings/di/interface/defs.d.ts +2 -1
  22. package/import/typings/di/interface/injector.d.ts +2 -2
  23. package/import/typings/di/interface/provider.d.ts +7 -7
  24. package/import/typings/di/metadata.d.ts +4 -4
  25. package/import/typings/di/provider_collection.d.ts +1 -12
  26. package/import/typings/di/r3_injector.d.ts +8 -6
  27. package/import/typings/di/scope.d.ts +1 -1
  28. package/import/typings/errors.d.ts +28 -3
  29. package/import/typings/render3/fields.d.ts +9 -0
  30. package/import/typings/util/decorators.d.ts +1 -0
  31. package/package.json +7 -7
  32. package/readme.md +4 -1
  33. package/transform/compiler/src/injectable_compiler_2.d.ts +0 -1
  34. package/transform/compiler/src/injectable_compiler_2.js +31 -16
  35. package/transform/compiler/src/output/output_ast.d.ts +53 -10
  36. package/transform/compiler/src/output/output_ast.js +211 -12
  37. package/transform/compiler/src/parse_util.js +10 -0
  38. package/transform/compiler/src/render3/partial/api.js +1 -1
  39. package/transform/compiler/src/render3/r3_factory.d.ts +0 -8
  40. package/transform/compiler/src/render3/r3_factory.js +5 -4
  41. package/transform/compiler/src/render3/r3_identifiers.js +37 -37
  42. package/transform/compiler/src/render3/view/util.js +1 -3
  43. package/transform/compiler-cli/src/ngtsc/annotations/common/src/di.js +2 -4
  44. package/transform/compiler-cli/src/ngtsc/annotations/common/src/factory.js +1 -0
  45. package/transform/compiler-cli/src/ngtsc/annotations/common/src/util.d.ts +1 -1
  46. package/transform/compiler-cli/src/ngtsc/annotations/common/src/util.js +5 -9
  47. package/transform/compiler-cli/src/ngtsc/annotations/src/injectable.d.ts +2 -1
  48. package/transform/compiler-cli/src/ngtsc/annotations/src/injectable.js +12 -8
  49. package/transform/compiler-cli/src/ngtsc/diagnostics/error.d.ts +2 -2
  50. package/transform/compiler-cli/src/ngtsc/diagnostics/error.js +8 -4
  51. package/transform/compiler-cli/src/ngtsc/diagnostics/error_code.js +1 -1
  52. package/transform/compiler-cli/src/ngtsc/imports/src/default.js +1 -2
  53. package/transform/compiler-cli/src/ngtsc/reflection/src/host.d.ts +24 -173
  54. package/transform/compiler-cli/src/ngtsc/reflection/src/host.js +2 -51
  55. package/transform/compiler-cli/src/ngtsc/reflection/src/typescript.d.ts +5 -3
  56. package/transform/compiler-cli/src/ngtsc/reflection/src/typescript.js +5 -10
  57. package/transform/compiler-cli/src/ngtsc/transform/src/api.d.ts +5 -23
  58. package/transform/compiler-cli/src/ngtsc/transform/src/api.js +0 -21
  59. package/transform/compiler-cli/src/ngtsc/transform/src/utils.js +1 -2
  60. package/transform/compiler-cli/src/ngtsc/translator/src/api/ast_factory.d.ts +7 -0
  61. package/transform/compiler-cli/src/ngtsc/translator/src/context.js +1 -0
  62. package/transform/compiler-cli/src/ngtsc/translator/src/import_manager.js +4 -2
  63. package/transform/compiler-cli/src/ngtsc/translator/src/translator.d.ts +1 -0
  64. package/transform/compiler-cli/src/ngtsc/translator/src/translator.js +10 -4
  65. package/transform/compiler-cli/src/ngtsc/translator/src/typescript_ast_factory.d.ts +2 -1
  66. package/transform/compiler-cli/src/ngtsc/translator/src/typescript_ast_factory.js +20 -16
  67. package/transform/injectable-transform.d.ts +2 -2
  68. package/transform/injectable-transform.js +32 -6
  69. package/import/es2015/di/provider_collection.js +0 -244
  70. package/import/es2015/render3/fields.js +0 -11
  71. /package/import/{es2015 → es2022}/di/initializer_token.js +0 -0
  72. /package/import/{es2015 → es2022}/di/inject_switch.js +0 -0
  73. /package/import/{es2015 → es2022}/di/injectable.js +0 -0
  74. /package/import/{es2015 → es2022}/di/injector_marker.js +0 -0
  75. /package/import/{es2015 → es2022}/di/injector_token.js +0 -0
  76. /package/import/{es2015 → es2022}/di/interface/provider.js +0 -0
  77. /package/import/{es2015 → es2022}/di/internal_tokens.js +0 -0
  78. /package/import/{es2015 → es2022}/di/metadata.js +0 -0
  79. /package/import/{es2015 → es2022}/di/null_injector.js +0 -0
  80. /package/import/{es2015 → es2022}/di/provider_token.js +0 -0
  81. /package/import/{es2015 → es2022}/di/scope.js +0 -0
  82. /package/import/{es2015 → es2022}/error_details_base_url.js +0 -0
  83. /package/import/{es2015 → es2022}/index.js +0 -0
  84. /package/import/{es2015 → es2022}/interface/lifecycle_hooks.js +0 -0
  85. /package/import/{es2015 → es2022}/interface/type.js +0 -0
  86. /package/import/{es2015 → es2022}/render3/definition_factory.js +0 -0
  87. /package/import/{es2015 → es2022}/render3/di.js +0 -0
  88. /package/import/{es2015 → es2022}/render3/errors_di.js +0 -0
  89. /package/import/{es2015 → es2022}/render3/instructions/di.js +0 -0
  90. /package/import/{es2015 → es2022}/render3/util/stringify_utils.js +0 -0
  91. /package/import/{es2015 → es2022}/util/array_utils.js +0 -0
  92. /package/import/{es2015 → es2022}/util/closure.js +0 -0
  93. /package/import/{es2015 → es2022}/util/decorators.js +0 -0
  94. /package/import/{es2015 → es2022}/util/empty.js +0 -0
  95. /package/import/{es2015 → es2022}/util/property.js +0 -0
  96. /package/import/{es2015 → es2022}/util/stringify.js +0 -0
@@ -108,9 +108,11 @@ function makeParamDecorator(name, props, parentClass) {
108
108
  *
109
109
  * Note: the `message` argument contains a descriptive error message as a string in development
110
110
  * mode (when the `ngDevMode` is defined). In production mode (after tree-shaking pass), the
111
- * `message` argument becomes `false`, thus we account for it in the typings and the runtime logic.
111
+ * `message` argument becomes `false`, thus we account for it in the typings and the runtime
112
+ * logic.
112
113
  */
113
114
  class RuntimeError extends Error {
115
+ code;
114
116
  constructor(code, message) {
115
117
  super(formatRuntimeError(code, message));
116
118
  this.code = code;
@@ -125,7 +127,7 @@ function formatRuntimeError(code, message) {
125
127
  // generate a link to the error details page on angular.io.
126
128
  // We also prepend `0` to non-compile-time errors.
127
129
  const fullCode = `NG0${Math.abs(code)}`;
128
- let errorMessage = `${fullCode}${message ? ': ' + message.trim() : ''}`;
130
+ let errorMessage = `${fullCode}${message ? ': ' + message : ''}`;
129
131
  if (false) {
130
132
  }
131
133
  return errorMessage;
@@ -195,9 +197,36 @@ const __forward_ref__ = getClosureSafeProperty({
195
197
  * DI is declared, but not yet defined. It is also used when the `token` which we use when creating
196
198
  * a query is not yet defined.
197
199
  *
200
+ * `forwardRef` is also used to break circularities in standalone components imports.
201
+ *
198
202
  * @usageNotes
199
- * ### Example
203
+ * ### Circular dependency example
200
204
  * {@example core/di/ts/forward_ref/forward_ref_spec.ts region='forward_ref'}
205
+ *
206
+ * ### Circular standalone reference import example
207
+ * ```ts
208
+ * @Component({
209
+ * standalone: true,
210
+ * imports: [ChildComponent],
211
+ * selector: 'app-parent',
212
+ * template: `<app-child [hideParent]="hideParent"></app-child>`,
213
+ * })
214
+ * export class ParentComponent {
215
+ * @Input() hideParent: boolean;
216
+ * }
217
+ *
218
+ *
219
+ * @Component({
220
+ * standalone: true,
221
+ * imports: [CommonModule, forwardRef(() => ParentComponent)],
222
+ * selector: 'app-child',
223
+ * template: `<app-parent *ngIf="!hideParent"></app-parent>`,
224
+ * })
225
+ * export class ChildComponent {
226
+ * @Input() hideParent: boolean;
227
+ * }
228
+ * ```
229
+ *
201
230
  * @publicApi
202
231
  */
203
232
  function forwardRef(forwardRefFn) {
@@ -217,7 +246,7 @@ function forwardRef(forwardRefFn) {
217
246
  *
218
247
  * {@example core/di/ts/forward_ref/forward_ref_spec.ts region='resolve_forward_ref'}
219
248
  *
220
- * @see `forwardRef`
249
+ * @see {@link forwardRef}
221
250
  * @publicApi
222
251
  */
223
252
  function resolveForwardRef(type) {
@@ -262,7 +291,8 @@ function throwProviderNotFoundError(token, injectorName) {
262
291
  * with an `@NgModule` or other `InjectorType`, or by specifying that this injectable should be
263
292
  * provided in the `'root'` injector, which will be the application-level injector in most apps.
264
293
  * * `factory` gives the zero argument function which will create an instance of the injectable.
265
- * The factory can call `inject` to access the `Injector` and request injection of dependencies.
294
+ * The factory can call [`inject`](api/core/inject) to access the `Injector` and request injection
295
+ * of dependencies.
266
296
  *
267
297
  * @codeGenApi
268
298
  * @publicApi This instruction has been emitted by ViewEngine for some time and is deployed to npm.
@@ -325,27 +355,12 @@ function getOwnDefinition(type, field) {
325
355
  function getInheritedInjectableDef(type) {
326
356
  const def = type && (type[NG_PROV_DEF] || null);
327
357
  if (def) {
328
- const typeName = getTypeName(type);
329
358
  return def;
330
359
  }
331
360
  else {
332
361
  return null;
333
362
  }
334
363
  }
335
- /** Gets the name of a type, accounting for some cross-browser differences. */
336
- function getTypeName(type) {
337
- // `Function.prototype.name` behaves differently between IE and other browsers. In most browsers
338
- // it'll always return the name of the function itself, no matter how many other functions it
339
- // inherits from. On IE the function doesn't have its own `name` property, but it takes it from
340
- // the lowest level in the prototype chain. E.g. if we have `class Foo extends Parent` most
341
- // browsers will evaluate `Foo.name` to `Foo` while IE will return `Parent`. We work around
342
- // the issue by converting the function to a string and parsing its name out that way via a regex.
343
- if (type.hasOwnProperty('name')) {
344
- return type.name;
345
- }
346
- const match = ('' + type).match(/^function\s*([^\s(]+)/);
347
- return match === null ? '' : match[1];
348
- }
349
364
  /**
350
365
  * Read the injector def type in a way which is immune to accidentally reading inherited value.
351
366
  *
@@ -374,7 +389,7 @@ const NG_INJ_DEF = getClosureSafeProperty({
374
389
  * Injection flags for DI.
375
390
  *
376
391
  * @publicApi
377
- * @deprecated use an options object for `inject` instead.
392
+ * @deprecated use an options object for [`inject`](api/core/inject) instead.
378
393
  */
379
394
  exports.InjectFlags = void 0;
380
395
  (function (InjectFlags) {
@@ -466,6 +481,9 @@ const SOURCE = '__source';
466
481
  * - Injector instance: Use the injector for resolution.
467
482
  */
468
483
  let _currentInjector = undefined;
484
+ function getCurrentInjector() {
485
+ return _currentInjector;
486
+ }
469
487
  function setCurrentInjector(injector) {
470
488
  const former = _currentInjector;
471
489
  _currentInjector = injector;
@@ -479,7 +497,8 @@ function injectInjectorOnly(token, flags = exports.InjectFlags.Default) {
479
497
  return injectRootLimpMode(token, undefined, flags);
480
498
  }
481
499
  else {
482
- return _currentInjector.get(token, flags & exports.InjectFlags.Optional ? null : undefined, flags);
500
+ const value = _currentInjector.get(token, flags & exports.InjectFlags.Optional ? null : undefined, flags);
501
+ return value;
483
502
  }
484
503
  }
485
504
  function ɵɵinject(token, flags = exports.InjectFlags.Default) {
@@ -499,13 +518,14 @@ function ɵɵinvalidFactoryDep(index) {
499
518
  }
500
519
  /**
501
520
  * Injects a token from the currently active injector.
502
- * `inject` is only supported during instantiation of a dependency by the DI system. It can be used
503
- * during:
521
+ * `inject` is only supported in an [injection context](/guide/dependency-injection-context). It can
522
+ * be used during:
504
523
  * - Construction (via the `constructor`) of a class being instantiated by the DI system, such
505
524
  * as an `@Injectable` or `@Component`.
506
525
  * - In the initializer for fields of such classes.
507
526
  * - In the factory function specified for `useFactory` of a `Provider` or an `@Injectable`.
508
527
  * - In the `factory` function specified for an `InjectionToken`.
528
+ * - In a stackframe of a function call in a DI context
509
529
  *
510
530
  * @param token A token that represents a dependency that should be injected.
511
531
  * @param flags Optional flags that control how injection is executed.
@@ -730,6 +750,17 @@ attachInjectFlag(makeParamDecorator('SkipSelf'), 4 /* InternalInjectFlags.SkipSe
730
750
  const NG_FACTORY_DEF = getClosureSafeProperty({
731
751
  ɵfac: getClosureSafeProperty,
732
752
  });
753
+ /**
754
+ * The `NG_ENV_ID` field on a DI token indicates special processing in the `EnvironmentInjector`:
755
+ * getting such tokens from the `EnvironmentInjector` will bypass the standard DI resolution
756
+ * strategy and instead will return implementation produced by the `NG_ENV_ID` factory function.
757
+ *
758
+ * This particular retrieval of DI tokens is mostly done to eliminate circular dependencies and
759
+ * improve tree-shaking.
760
+ */
761
+ const NG_ENV_ID = getClosureSafeProperty({
762
+ __NG_ENV_ID__: getClosureSafeProperty,
763
+ });
733
764
 
734
765
  /**
735
766
  * @license
@@ -802,7 +833,7 @@ if (false) {
802
833
  * (possibly by creating) a default value of the parameterized type `T`. This sets up the
803
834
  * `InjectionToken` using this factory as a provider as if it was defined explicitly in the
804
835
  * application's root injector. If the factory function, which takes zero arguments, needs to inject
805
- * dependencies, it can do so using the `inject` function.
836
+ * dependencies, it can do so using the [`inject`](api/core/inject) function.
806
837
  * As you can see in the Tree-shakable InjectionToken example below.
807
838
  *
808
839
  * Additionally, if a `factory` is specified you can also specify the `providedIn` option, which
@@ -827,6 +858,10 @@ if (false) {
827
858
  * @publicApi
828
859
  */
829
860
  class InjectionToken {
861
+ _desc;
862
+ /** @internal */
863
+ ngMetadataName = 'InjectionToken';
864
+ ɵprov;
830
865
  /**
831
866
  * @param _desc Description for the token,
832
867
  * used only for debugging purposes,
@@ -835,8 +870,6 @@ class InjectionToken {
835
870
  */
836
871
  constructor(_desc, options) {
837
872
  this._desc = _desc;
838
- /** @internal */
839
- this.ngMetadataName = 'InjectionToken';
840
873
  this.ɵprov = undefined;
841
874
  if (typeof options == 'number') {
842
875
  }
@@ -942,7 +975,7 @@ class NullInjector {
942
975
  */
943
976
  /**
944
977
  * Wrap an array of `Provider`s into `EnvironmentProviders`, preventing them from being accidentally
945
- * referenced in `@Component in a component injector.
978
+ * referenced in `@Component` in a component injector.
946
979
  */
947
980
  function makeEnvironmentProviders(providers) {
948
981
  return {
@@ -999,9 +1032,12 @@ function internalImportProvidersFrom(checkForStandaloneCmp, ...sources) {
999
1032
  const providersOut = [];
1000
1033
  const dedup = new Set(); // already seen types
1001
1034
  let injectorTypesWithProviders;
1035
+ const collectProviders = (provider) => {
1036
+ providersOut.push(provider);
1037
+ };
1002
1038
  // Collect all providers from `ModuleWithProviders` types.
1003
1039
  if (injectorTypesWithProviders !== undefined) {
1004
- processInjectorTypesWithProviders(injectorTypesWithProviders, providersOut);
1040
+ processInjectorTypesWithProviders(injectorTypesWithProviders, collectProviders);
1005
1041
  }
1006
1042
  return providersOut;
1007
1043
  }
@@ -1009,145 +1045,11 @@ function internalImportProvidersFrom(checkForStandaloneCmp, ...sources) {
1009
1045
  * Collects all providers from the list of `ModuleWithProviders` and appends them to the provided
1010
1046
  * array.
1011
1047
  */
1012
- function processInjectorTypesWithProviders(typesWithProviders, providersOut) {
1048
+ function processInjectorTypesWithProviders(typesWithProviders, visitor) {
1013
1049
  for (let i = 0; i < typesWithProviders.length; i++) {
1014
1050
  const { ngModule, providers } = typesWithProviders[i];
1015
1051
  }
1016
1052
  }
1017
- /**
1018
- * The logic visits an `InjectorType`, an `InjectorTypeWithProviders`, or a standalone
1019
- * `ComponentType`, and all of its transitive providers and collects providers.
1020
- *
1021
- * If an `InjectorTypeWithProviders` that declares providers besides the type is specified,
1022
- * the function will return "true" to indicate that the providers of the type definition need
1023
- * to be processed. This allows us to process providers of injector types after all imports of
1024
- * an injector definition are processed. (following View Engine semantics: see FW-1349)
1025
- */
1026
- function walkProviderTree(container, providersOut, parents, dedup) {
1027
- container = resolveForwardRef(container);
1028
- if (!container)
1029
- return false;
1030
- // The actual type which had the definition. Usually `container`, but may be an unwrapped type
1031
- // from `InjectorTypeWithProviders`.
1032
- let defType = null;
1033
- let injDef = getInjectorDef(container);
1034
- const cmpDef = !injDef && null;
1035
- if (!injDef && !cmpDef) {
1036
- // `container` is not an injector type or a component type. It might be:
1037
- // * An `InjectorTypeWithProviders` that wraps an injector type.
1038
- // * A standalone directive or pipe that got pulled in from a standalone component's
1039
- // dependencies.
1040
- // Try to unwrap it as an `InjectorTypeWithProviders` first.
1041
- const ngModule = container.ngModule;
1042
- injDef = getInjectorDef(ngModule);
1043
- if (injDef) {
1044
- defType = ngModule;
1045
- }
1046
- else {
1047
- // Not a component or injector type, so ignore it.
1048
- return false;
1049
- }
1050
- }
1051
- else if (cmpDef && !cmpDef.standalone) {
1052
- return false;
1053
- }
1054
- else {
1055
- defType = container;
1056
- }
1057
- // Check for circular dependencies.
1058
- if (false) {
1059
- }
1060
- // Check for multiple imports of the same module
1061
- const isDuplicate = dedup.has(defType);
1062
- if (cmpDef) {
1063
- if (isDuplicate) {
1064
- // This component definition has already been processed.
1065
- return false;
1066
- }
1067
- dedup.add(defType);
1068
- if (cmpDef.dependencies) {
1069
- const deps = typeof cmpDef.dependencies === 'function'
1070
- ? cmpDef.dependencies()
1071
- : cmpDef.dependencies;
1072
- for (const dep of deps) {
1073
- walkProviderTree(dep, providersOut, parents, dedup);
1074
- }
1075
- }
1076
- }
1077
- else if (injDef) {
1078
- // First, include providers from any imports.
1079
- if (injDef.imports != null && !isDuplicate) {
1080
- // Before processing defType's imports, add it to the set of parents. This way, if it ends
1081
- // up deeply importing itself, this can be detected.
1082
- // Add it to the set of dedups. This way we can detect multiple imports of the same module
1083
- dedup.add(defType);
1084
- let importTypesWithProviders;
1085
- try {
1086
- deepForEach(injDef.imports, (imported) => {
1087
- if (walkProviderTree(imported, providersOut, parents, dedup)) {
1088
- importTypesWithProviders || (importTypesWithProviders = []);
1089
- // If the processed import is an injector type with providers, we store it in the
1090
- // list of import types with providers, so that we can process those afterwards.
1091
- importTypesWithProviders.push(imported);
1092
- }
1093
- });
1094
- }
1095
- finally {
1096
- // Remove it from the parents set when finished.
1097
- }
1098
- // Imports which are declared with providers (TypeWithProviders) need to be processed
1099
- // after all imported modules are processed. This is similar to how View Engine
1100
- // processes/merges module imports in the metadata resolver. See: FW-1349.
1101
- if (importTypesWithProviders !== undefined) {
1102
- processInjectorTypesWithProviders(importTypesWithProviders, providersOut);
1103
- }
1104
- }
1105
- if (!isDuplicate) {
1106
- // Track the InjectorType and add a provider for it.
1107
- // It's important that this is done after the def's imports.
1108
- const factory = getFactoryDef(defType) || (() => new defType());
1109
- // Append extra providers to make more info available for consumers (to retrieve an injector
1110
- // type), as well as internally (to calculate an injection scope correctly and eagerly
1111
- // instantiate a `defType` when an injector is created).
1112
- providersOut.push(
1113
- // Provider to create `defType` using its factory.
1114
- { provide: defType, useFactory: factory, deps: EMPTY_ARRAY },
1115
- // Make this `defType` available to an internal logic that calculates injector scope.
1116
- { provide: INJECTOR_DEF_TYPES, useValue: defType, multi: true },
1117
- // Provider to eagerly instantiate `defType` via `ENVIRONMENT_INITIALIZER`.
1118
- {
1119
- provide: ENVIRONMENT_INITIALIZER,
1120
- useValue: () => ɵɵinject(defType),
1121
- multi: true,
1122
- } //
1123
- );
1124
- }
1125
- // Next, include providers listed on the definition itself.
1126
- const defProviders = injDef.providers;
1127
- if (defProviders != null && !isDuplicate) {
1128
- const injectorType = container;
1129
- }
1130
- }
1131
- else {
1132
- // Should not happen, but just in case.
1133
- return false;
1134
- }
1135
- return (defType !== container &&
1136
- container.providers !== undefined);
1137
- }
1138
- function deepForEachProvider(providers, fn) {
1139
- for (let provider of providers) {
1140
- if (isEnvironmentProviders(provider)) {
1141
- provider = provider.ɵproviders;
1142
- }
1143
- if (Array.isArray(provider)) {
1144
- deepForEachProvider(provider, fn);
1145
- }
1146
- else {
1147
- fn(provider);
1148
- }
1149
- }
1150
- }
1151
1053
  const USE_VALUE = getClosureSafeProperty({
1152
1054
  provide: String,
1153
1055
  useValue: getClosureSafeProperty,
@@ -1218,29 +1120,33 @@ function getNullInjector() {
1218
1120
  class EnvironmentInjector {
1219
1121
  }
1220
1122
  class R3Injector extends EnvironmentInjector {
1123
+ parent;
1124
+ source;
1125
+ scopes;
1126
+ /**
1127
+ * Map of tokens to records which contain the instances of those tokens.
1128
+ * - `null` value implies that we don't have the record. Used by tree-shakable injectors
1129
+ * to prevent further searches.
1130
+ */
1131
+ records = new Map();
1132
+ /**
1133
+ * Set of values instantiated by this injector which contain `ngOnDestroy` lifecycle hooks.
1134
+ */
1135
+ _ngOnDestroyHooks = new Set();
1136
+ _onDestroyHooks = [];
1221
1137
  /**
1222
1138
  * Flag indicating that this injector was previously destroyed.
1223
1139
  */
1224
1140
  get destroyed() {
1225
1141
  return this._destroyed;
1226
1142
  }
1143
+ _destroyed = false;
1144
+ injectorDefTypes;
1227
1145
  constructor(providers, parent, source, scopes) {
1228
1146
  super();
1229
1147
  this.parent = parent;
1230
1148
  this.source = source;
1231
1149
  this.scopes = scopes;
1232
- /**
1233
- * Map of tokens to records which contain the instances of those tokens.
1234
- * - `null` value implies that we don't have the record. Used by tree-shakable injectors
1235
- * to prevent further searches.
1236
- */
1237
- this.records = new Map();
1238
- /**
1239
- * Set of values instantiated by this injector which contain `ngOnDestroy` lifecycle hooks.
1240
- */
1241
- this._ngOnDestroyHooks = new Set();
1242
- this._onDestroyHooks = [];
1243
- this._destroyed = false;
1244
1150
  // Start off by creating Records for every provider.
1245
1151
  forEachSingleProvider(providers, (provider) => this.processProvider(provider));
1246
1152
  // Make sure the INJECTOR token provides this injector.
@@ -1272,7 +1178,11 @@ class R3Injector extends EnvironmentInjector {
1272
1178
  for (const service of this._ngOnDestroyHooks) {
1273
1179
  service.ngOnDestroy();
1274
1180
  }
1275
- for (const hook of this._onDestroyHooks) {
1181
+ const onDestroyHooks = this._onDestroyHooks;
1182
+ // Reset the _onDestroyHooks array before iterating over it to prevent hooks that unregister
1183
+ // themselves from mutating the array during iteration.
1184
+ this._onDestroyHooks = [];
1185
+ for (const hook of onDestroyHooks) {
1276
1186
  hook();
1277
1187
  }
1278
1188
  }
@@ -1281,16 +1191,19 @@ class R3Injector extends EnvironmentInjector {
1281
1191
  this.records.clear();
1282
1192
  this._ngOnDestroyHooks.clear();
1283
1193
  this.injectorDefTypes.clear();
1284
- this._onDestroyHooks.length = 0;
1285
1194
  }
1286
1195
  }
1287
1196
  onDestroy(callback) {
1197
+ this.assertNotDestroyed();
1288
1198
  this._onDestroyHooks.push(callback);
1199
+ return () => this.removeOnDestroy(callback);
1289
1200
  }
1290
1201
  runInContext(fn) {
1291
1202
  this.assertNotDestroyed();
1292
1203
  const previousInjector = setCurrentInjector(this);
1293
1204
  const previousInjectImplementation = setInjectImplementation(undefined);
1205
+ if (false) {
1206
+ }
1294
1207
  try {
1295
1208
  return fn();
1296
1209
  }
@@ -1301,8 +1214,13 @@ class R3Injector extends EnvironmentInjector {
1301
1214
  }
1302
1215
  get(token, notFoundValue = THROW_IF_NOT_FOUND, flags = exports.InjectFlags.Default) {
1303
1216
  this.assertNotDestroyed();
1217
+ if (token.hasOwnProperty(NG_ENV_ID)) {
1218
+ return token[NG_ENV_ID](this);
1219
+ }
1304
1220
  flags = convertToBitFlags(flags);
1305
1221
  // Set the injection context.
1222
+ if (false) {
1223
+ }
1306
1224
  const previousInjector = setCurrentInjector(this);
1307
1225
  const previousInjectImplementation = setInjectImplementation(undefined);
1308
1226
  try {
@@ -1370,6 +1288,8 @@ class R3Injector extends EnvironmentInjector {
1370
1288
  resolveInjectorInitializers() {
1371
1289
  const previousInjector = setCurrentInjector(this);
1372
1290
  const previousInjectImplementation = setInjectImplementation(undefined);
1291
+ if (false) {
1292
+ }
1373
1293
  try {
1374
1294
  const initializers = this.get(ENVIRONMENT_INITIALIZER.multi, EMPTY_ARRAY, exports.InjectFlags.Self);
1375
1295
  if (false) {
@@ -1408,6 +1328,8 @@ class R3Injector extends EnvironmentInjector {
1408
1328
  : resolveForwardRef(provider && provider.provide);
1409
1329
  // Construct a `Record` for the provider.
1410
1330
  const record = providerToRecord(provider);
1331
+ if (false) {
1332
+ }
1411
1333
  if (!isTypeProvider(provider) && provider.multi === true) {
1412
1334
  // If the provider indicates that it's a multi-provider, process it specially.
1413
1335
  // First check whether it's been defined already.
@@ -1437,7 +1359,11 @@ class R3Injector extends EnvironmentInjector {
1437
1359
  }
1438
1360
  else if (record.value === NOT_YET) {
1439
1361
  record.value = CIRCULAR;
1440
- record.value = record.factory();
1362
+ if (false) {
1363
+ }
1364
+ else {
1365
+ record.value = record.factory();
1366
+ }
1441
1367
  }
1442
1368
  if (typeof record.value === 'object' &&
1443
1369
  record.value &&
@@ -1458,6 +1384,12 @@ class R3Injector extends EnvironmentInjector {
1458
1384
  return this.injectorDefTypes.has(providedIn);
1459
1385
  }
1460
1386
  }
1387
+ removeOnDestroy(callback) {
1388
+ const destroyCBIdx = this._onDestroyHooks.indexOf(callback);
1389
+ if (destroyCBIdx !== -1) {
1390
+ this._onDestroyHooks.splice(destroyCBIdx, 1);
1391
+ }
1392
+ }
1461
1393
  }
1462
1394
  function injectableDefOrInjectorDefFactory(token) {
1463
1395
  // Most tokens will have an injectable def directly on them, which specifies a factory directly.
@@ -1589,8 +1521,6 @@ function forEachSingleProvider(providers, fn) {
1589
1521
  */
1590
1522
  /**
1591
1523
  * Create a new `Injector` which is configured using a `defType` of `InjectorType<any>`s.
1592
- *
1593
- * @publicApi
1594
1524
  */
1595
1525
  function createInjector(defType, parent = null, additionalProviders = null, name) {
1596
1526
  const injector = createInjectorWithoutInjectorInstances(defType, parent, additionalProviders, name);
@@ -1624,7 +1554,7 @@ function createInjectorWithoutInjectorInstances(defType, parent = null, addition
1624
1554
  * dependencies of various types with [injection tokens](guide/glossary#di-token).
1625
1555
  *
1626
1556
  * @see ["DI Providers"](guide/dependency-injection-providers).
1627
- * @see `StaticProvider`
1557
+ * @see {@link StaticProvider}
1628
1558
  *
1629
1559
  * @usageNotes
1630
1560
  *
@@ -1643,30 +1573,29 @@ function createInjectorWithoutInjectorInstances(defType, parent = null, addition
1643
1573
  * @publicApi
1644
1574
  */
1645
1575
  class Injector {
1576
+ static THROW_IF_NOT_FOUND = THROW_IF_NOT_FOUND;
1577
+ static NULL = new NullInjector();
1646
1578
  static create(options, parent) {
1647
- var _a;
1648
1579
  if (Array.isArray(options)) {
1649
1580
  return createInjector({ name: '' }, parent, options, '');
1650
1581
  }
1651
1582
  else {
1652
- const name = (_a = options.name) !== null && _a !== void 0 ? _a : '';
1583
+ const name = options.name ?? '';
1653
1584
  return createInjector({ name }, options.parent, options.providers, name);
1654
1585
  }
1655
1586
  }
1587
+ /** @nocollapse */
1588
+ static ɵprov = /** @pureOrBreakMyCode */ ɵɵdefineInjectable({
1589
+ token: Injector,
1590
+ providedIn: 'any',
1591
+ factory: () => ɵɵinject(INJECTOR),
1592
+ });
1593
+ /**
1594
+ * @internal
1595
+ * @nocollapse
1596
+ */
1597
+ static __NG_ELEMENT_ID__ = -1 /* InjectorMarkers.Injector */;
1656
1598
  }
1657
- Injector.THROW_IF_NOT_FOUND = THROW_IF_NOT_FOUND;
1658
- Injector.NULL = new NullInjector();
1659
- /** @nocollapse */
1660
- Injector.ɵprov = ɵɵdefineInjectable({
1661
- token: Injector,
1662
- providedIn: 'any',
1663
- factory: () => ɵɵinject(INJECTOR),
1664
- });
1665
- /**
1666
- * @internal
1667
- * @nocollapse
1668
- */
1669
- Injector.__NG_ELEMENT_ID__ = -1 /* InjectorMarkers.Injector */;
1670
1599
 
1671
1600
  /**
1672
1601
  * Throws an error indicating that a factory function could not be generated by the compiler for a
@@ -1751,6 +1680,7 @@ exports.attachInjectFlag = attachInjectFlag;
1751
1680
  exports.catchInjectorError = catchInjectorError;
1752
1681
  exports.convertToBitFlags = convertToBitFlags;
1753
1682
  exports.formatError = formatError;
1683
+ exports.getCurrentInjector = getCurrentInjector;
1754
1684
  exports.getInheritedInjectableDef = getInheritedInjectableDef;
1755
1685
  exports.getInjectFlag = getInjectFlag;
1756
1686
  exports.getInjectableDef = getInjectableDef;
@@ -11,8 +11,6 @@ import { importProvidersFrom } from './provider_collection';
11
11
  import { getNullInjector, R3Injector } from './r3_injector';
12
12
  /**
13
13
  * Create a new `Injector` which is configured using a `defType` of `InjectorType<any>`s.
14
- *
15
- * @publicApi
16
14
  */
17
15
  export function createInjector(defType, parent = null, additionalProviders = null, name) {
18
16
  const injector = createInjectorWithoutInjectorInstances(defType, parent, additionalProviders, name);
@@ -17,9 +17,36 @@ const __forward_ref__ = getClosureSafeProperty({
17
17
  * DI is declared, but not yet defined. It is also used when the `token` which we use when creating
18
18
  * a query is not yet defined.
19
19
  *
20
+ * `forwardRef` is also used to break circularities in standalone components imports.
21
+ *
20
22
  * @usageNotes
21
- * ### Example
23
+ * ### Circular dependency example
22
24
  * {@example core/di/ts/forward_ref/forward_ref_spec.ts region='forward_ref'}
25
+ *
26
+ * ### Circular standalone reference import example
27
+ * ```ts
28
+ * @Component({
29
+ * standalone: true,
30
+ * imports: [ChildComponent],
31
+ * selector: 'app-parent',
32
+ * template: `<app-child [hideParent]="hideParent"></app-child>`,
33
+ * })
34
+ * export class ParentComponent {
35
+ * @Input() hideParent: boolean;
36
+ * }
37
+ *
38
+ *
39
+ * @Component({
40
+ * standalone: true,
41
+ * imports: [CommonModule, forwardRef(() => ParentComponent)],
42
+ * selector: 'app-child',
43
+ * template: `<app-parent *ngIf="!hideParent"></app-parent>`,
44
+ * })
45
+ * export class ChildComponent {
46
+ * @Input() hideParent: boolean;
47
+ * }
48
+ * ```
49
+ *
23
50
  * @publicApi
24
51
  */
25
52
  export function forwardRef(forwardRefFn) {
@@ -39,7 +66,7 @@ export function forwardRef(forwardRefFn) {
39
66
  *
40
67
  * {@example core/di/ts/forward_ref/forward_ref_spec.ts region='resolve_forward_ref'}
41
68
  *
42
- * @see `forwardRef`
69
+ * @see {@link forwardRef}
43
70
  * @publicApi
44
71
  */
45
72
  export function resolveForwardRef(type) {
@@ -26,7 +26,7 @@ import { ɵɵdefineInjectable } from './interface/defs';
26
26
  * (possibly by creating) a default value of the parameterized type `T`. This sets up the
27
27
  * `InjectionToken` using this factory as a provider as if it was defined explicitly in the
28
28
  * application's root injector. If the factory function, which takes zero arguments, needs to inject
29
- * dependencies, it can do so using the `inject` function.
29
+ * dependencies, it can do so using the [`inject`](api/core/inject) function.
30
30
  * As you can see in the Tree-shakable InjectionToken example below.
31
31
  *
32
32
  * Additionally, if a `factory` is specified you can also specify the `providedIn` option, which
@@ -51,6 +51,10 @@ import { ɵɵdefineInjectable } from './interface/defs';
51
51
  * @publicApi
52
52
  */
53
53
  export class InjectionToken {
54
+ _desc;
55
+ /** @internal */
56
+ ngMetadataName = 'InjectionToken';
57
+ ɵprov;
54
58
  /**
55
59
  * @param _desc Description for the token,
56
60
  * used only for debugging purposes,
@@ -59,8 +63,6 @@ export class InjectionToken {
59
63
  */
60
64
  constructor(_desc, options) {
61
65
  this._desc = _desc;
62
- /** @internal */
63
- this.ngMetadataName = 'InjectionToken';
64
66
  this.ɵprov = undefined;
65
67
  if (typeof options == 'number') {
66
68
  }