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