@angular/core 16.2.0-next.3 → 16.2.0-rc.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 (51) hide show
  1. package/esm2022/rxjs-interop/src/to_signal.mjs +1 -1
  2. package/esm2022/src/core.mjs +2 -1
  3. package/esm2022/src/core_private_export.mjs +2 -1
  4. package/esm2022/src/core_render3_private_export.mjs +3 -2
  5. package/esm2022/src/di/contextual.mjs +7 -1
  6. package/esm2022/src/di/create_injector.mjs +1 -3
  7. package/esm2022/src/di/injector.mjs +1 -1
  8. package/esm2022/src/di/injector_compatibility.mjs +5 -2
  9. package/esm2022/src/di/interface/provider.mjs +1 -1
  10. package/esm2022/src/di/provider_collection.mjs +17 -16
  11. package/esm2022/src/di/r3_injector.mjs +37 -2
  12. package/esm2022/src/errors.mjs +1 -1
  13. package/esm2022/src/hydration/api.mjs +7 -14
  14. package/esm2022/src/linker/view_container_ref.mjs +2 -2
  15. package/esm2022/src/metadata/di.mjs +5 -5
  16. package/esm2022/src/metadata/directives.mjs +1 -1
  17. package/esm2022/src/render3/after_render_hooks.mjs +210 -0
  18. package/esm2022/src/render3/component_ref.mjs +5 -9
  19. package/esm2022/src/render3/debug/framework_injector_profiler.mjs +212 -0
  20. package/esm2022/src/render3/debug/injector_profiler.mjs +103 -0
  21. package/esm2022/src/render3/di.mjs +32 -2
  22. package/esm2022/src/render3/di_setup.mjs +11 -4
  23. package/esm2022/src/render3/hooks.mjs +3 -3
  24. package/esm2022/src/render3/index.mjs +2 -2
  25. package/esm2022/src/render3/instructions/all.mjs +2 -1
  26. package/esm2022/src/render3/instructions/change_detection.mjs +16 -9
  27. package/esm2022/src/render3/instructions/defer.mjs +19 -0
  28. package/esm2022/src/render3/instructions/di.mjs +5 -2
  29. package/esm2022/src/render3/interfaces/view.mjs +1 -1
  30. package/esm2022/src/render3/jit/environment.mjs +2 -1
  31. package/esm2022/src/render3/pipe.mjs +12 -3
  32. package/esm2022/src/render3/util/global_utils.mjs +7 -1
  33. package/esm2022/src/render3/util/injector_discovery_utils.mjs +460 -0
  34. package/esm2022/src/render3/util/misc_utils.mjs +12 -1
  35. package/esm2022/src/util/coercion.mjs +11 -1
  36. package/esm2022/src/version.mjs +1 -1
  37. package/esm2022/testing/src/logger.mjs +3 -3
  38. package/fesm2022/core.mjs +1501 -453
  39. package/fesm2022/core.mjs.map +1 -1
  40. package/fesm2022/rxjs-interop.mjs +1 -1
  41. package/fesm2022/rxjs-interop.mjs.map +1 -1
  42. package/fesm2022/testing.mjs +3938 -3537
  43. package/fesm2022/testing.mjs.map +1 -1
  44. package/index.d.ts +215 -18
  45. package/package.json +1 -1
  46. package/rxjs-interop/index.d.ts +17 -15
  47. package/schematics/migrations/guard-and-resolve-interfaces/bundle.js +13 -13
  48. package/schematics/migrations/remove-module-id/bundle.js +14 -14
  49. package/schematics/ng-generate/standalone-migration/bundle.js +3628 -2718
  50. package/schematics/ng-generate/standalone-migration/bundle.js.map +4 -4
  51. package/testing/index.d.ts +1 -1
package/fesm2022/core.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Angular v16.2.0-next.3
2
+ * @license Angular v16.2.0-rc.0
3
3
  * (c) 2010-2022 Google LLC. https://angular.io/
4
4
  * License: MIT
5
5
  */
@@ -604,6 +604,100 @@ function initNgDevMode() {
604
604
  return false;
605
605
  }
606
606
 
607
+ let _injectorProfilerContext;
608
+ function getInjectorProfilerContext() {
609
+ !ngDevMode && throwError('getInjectorProfilerContext should never be called in production mode');
610
+ return _injectorProfilerContext;
611
+ }
612
+ function setInjectorProfilerContext(context) {
613
+ !ngDevMode && throwError('setInjectorProfilerContext should never be called in production mode');
614
+ const previous = _injectorProfilerContext;
615
+ _injectorProfilerContext = context;
616
+ return previous;
617
+ }
618
+ let injectorProfilerCallback = null;
619
+ /**
620
+ * Sets the callback function which will be invoked during certain DI events within the
621
+ * runtime (for example: injecting services, creating injectable instances, configuring providers)
622
+ *
623
+ * Warning: this function is *INTERNAL* and should not be relied upon in application's code.
624
+ * The contract of the function might be changed in any release and/or the function can be removed
625
+ * completely.
626
+ *
627
+ * @param profiler function provided by the caller or null value to disable profiling.
628
+ */
629
+ const setInjectorProfiler = (injectorProfiler) => {
630
+ !ngDevMode && throwError('setInjectorProfiler should never be called in production mode');
631
+ injectorProfilerCallback = injectorProfiler;
632
+ };
633
+ /**
634
+ * Injector profiler function which emits on DI events executed by the runtime.
635
+ *
636
+ * @param event InjectorProfilerEvent corresponding to the DI event being emitted
637
+ */
638
+ function injectorProfiler(event) {
639
+ !ngDevMode && throwError('Injector profiler should never be called in production mode');
640
+ if (injectorProfilerCallback != null /* both `null` and `undefined` */) {
641
+ injectorProfilerCallback(event);
642
+ }
643
+ }
644
+ /**
645
+ * Emits an InjectorProfilerEventType.ProviderConfigured to the injector profiler. The data in the
646
+ * emitted event includes the raw provider, as well as the token that provider is providing.
647
+ *
648
+ * @param provider A provider object
649
+ */
650
+ function emitProviderConfiguredEvent(provider, isViewProvider = false) {
651
+ !ngDevMode && throwError('Injector profiler should never be called in production mode');
652
+ injectorProfiler({
653
+ type: 2 /* InjectorProfilerEventType.ProviderConfigured */,
654
+ context: getInjectorProfilerContext(),
655
+ providerRecord: {
656
+ token: typeof provider === 'function' ? provider : resolveForwardRef(provider.provide),
657
+ provider,
658
+ isViewProvider
659
+ }
660
+ });
661
+ }
662
+ /**
663
+ * Emits an event to the injector profiler with the instance that was created. Note that
664
+ * the injector associated with this emission can be accessed by using getDebugInjectContext()
665
+ *
666
+ * @param instance an object created by an injector
667
+ */
668
+ function emitInstanceCreatedByInjectorEvent(instance) {
669
+ !ngDevMode && throwError('Injector profiler should never be called in production mode');
670
+ injectorProfiler({
671
+ type: 1 /* InjectorProfilerEventType.InstanceCreatedByInjector */,
672
+ context: getInjectorProfilerContext(),
673
+ instance: { value: instance }
674
+ });
675
+ }
676
+ /**
677
+ * @param token DI token associated with injected service
678
+ * @param value the instance of the injected service (i.e the result of `inject(token)`)
679
+ * @param flags the flags that the token was injected with
680
+ */
681
+ function emitInjectEvent(token, value, flags) {
682
+ !ngDevMode && throwError('Injector profiler should never be called in production mode');
683
+ injectorProfiler({
684
+ type: 0 /* InjectorProfilerEventType.Inject */,
685
+ context: getInjectorProfilerContext(),
686
+ service: { token, value, flags }
687
+ });
688
+ }
689
+ function runInInjectorProfilerContext(injector, token, callback) {
690
+ !ngDevMode &&
691
+ throwError('runInInjectorProfilerContext should never be called in production mode');
692
+ const prevInjectContext = setInjectorProfilerContext({ injector, token });
693
+ try {
694
+ callback();
695
+ }
696
+ finally {
697
+ setInjectorProfilerContext(prevInjectContext);
698
+ }
699
+ }
700
+
607
701
  const _THROW_IF_NOT_FOUND = {};
608
702
  const THROW_IF_NOT_FOUND = _THROW_IF_NOT_FOUND;
609
703
  /*
@@ -641,7 +735,9 @@ function injectInjectorOnly(token, flags = InjectFlags.Default) {
641
735
  return injectRootLimpMode(token, undefined, flags);
642
736
  }
643
737
  else {
644
- return _currentInjector.get(token, flags & InjectFlags.Optional ? null : undefined, flags);
738
+ const value = _currentInjector.get(token, flags & InjectFlags.Optional ? null : undefined, flags);
739
+ ngDevMode && emitInjectEvent(token, value, flags);
740
+ return value;
645
741
  }
646
742
  }
647
743
  function ɵɵinject(token, flags = InjectFlags.Default) {
@@ -3731,14 +3827,14 @@ function registerPostOrderHooks(tView, tNode) {
3731
3827
  * This is done by storing and maintaining flags in the view: the {@link InitPhaseState},
3732
3828
  * and the index within that phase. They can be seen as a cursor in the following structure:
3733
3829
  * [[onInit1, onInit2], [afterContentInit1], [afterViewInit1, afterViewInit2, afterViewInit3]]
3734
- * They are are stored as flags in LView[FLAGS].
3830
+ * They are stored as flags in LView[FLAGS].
3735
3831
  *
3736
3832
  * 2. Pre-order hooks can be executed in batches, because of the select instruction.
3737
3833
  * To be able to pause and resume their execution, we also need some state about the hook's array
3738
3834
  * that is being processed:
3739
3835
  * - the index of the next hook to be executed
3740
3836
  * - the number of init hooks already found in the processed part of the array
3741
- * They are are stored as flags in LView[PREORDER_HOOK_FLAGS].
3837
+ * They are stored as flags in LView[PREORDER_HOOK_FLAGS].
3742
3838
  */
3743
3839
  /**
3744
3840
  * Executes pre-order check hooks ( OnChanges, DoChanges) given a view where all the init hooks were
@@ -4498,7 +4594,18 @@ function lookupTokenUsingNodeInjector(tNode, lView, token, flags, notFoundValue)
4498
4594
  lookupTokenUsingModuleInjector(lView, token, flags, notFoundValue);
4499
4595
  }
4500
4596
  try {
4501
- const value = bloomHash(flags);
4597
+ let value;
4598
+ if (ngDevMode) {
4599
+ runInInjectorProfilerContext(new NodeInjector(getCurrentTNode(), getLView()), token, () => {
4600
+ value = bloomHash(flags);
4601
+ if (value != null) {
4602
+ emitInstanceCreatedByInjectorEvent(value);
4603
+ }
4604
+ });
4605
+ }
4606
+ else {
4607
+ value = bloomHash(flags);
4608
+ }
4502
4609
  if (value == null && !(flags & InjectFlags.Optional)) {
4503
4610
  throwProviderNotFoundError(token);
4504
4611
  }
@@ -4653,12 +4760,23 @@ function getNodeInjectable(lView, tView, index, tNode) {
4653
4760
  }
4654
4761
  const previousIncludeViewProviders = setIncludeViewProviders(factory.canSeeViewProviders);
4655
4762
  factory.resolving = true;
4763
+ let prevInjectContext;
4764
+ if (ngDevMode) {
4765
+ // tData indexes mirror the concrete instances in its corresponding LView.
4766
+ // lView[index] here is either the injectable instace itself or a factory,
4767
+ // therefore tData[index] is the constructor of that injectable or a
4768
+ // definition object that contains the constructor in a `.type` field.
4769
+ const token = tData[index].type || tData[index];
4770
+ const injector = new NodeInjector(tNode, lView);
4771
+ prevInjectContext = setInjectorProfilerContext({ injector, token });
4772
+ }
4656
4773
  const previousInjectImplementation = factory.injectImpl ? setInjectImplementation(factory.injectImpl) : null;
4657
4774
  const success = enterDI(lView, tNode, InjectFlags.Default);
4658
4775
  ngDevMode &&
4659
4776
  assertEqual(success, true, 'Because flags do not contain \`SkipSelf\' we expect this to always succeed.');
4660
4777
  try {
4661
4778
  value = lView[index] = factory.factory(undefined, tData, lView, tNode);
4779
+ ngDevMode && emitInstanceCreatedByInjectorEvent(value);
4662
4780
  // This code path is hit for both directives and providers.
4663
4781
  // For perf reasons, we want to avoid searching for hooks on providers.
4664
4782
  // It does no harm to try (the hooks just won't exist), but the extra
@@ -4671,6 +4789,7 @@ function getNodeInjectable(lView, tView, index, tNode) {
4671
4789
  }
4672
4790
  }
4673
4791
  finally {
4792
+ ngDevMode && setInjectorProfilerContext(prevInjectContext);
4674
4793
  previousInjectImplementation !== null &&
4675
4794
  setInjectImplementation(previousInjectImplementation);
4676
4795
  setIncludeViewProviders(previousIncludeViewProviders);
@@ -4732,6 +4851,12 @@ function bloomHasToken(bloomHash, injectorIndex, injectorView) {
4732
4851
  function shouldSearchParent(flags, isFirstHostTNode) {
4733
4852
  return !(flags & InjectFlags.Self) && !(flags & InjectFlags.Host && isFirstHostTNode);
4734
4853
  }
4854
+ function getNodeInjectorLView(nodeInjector) {
4855
+ return nodeInjector._lView;
4856
+ }
4857
+ function getNodeInjectorTNode(nodeInjector) {
4858
+ return nodeInjector._tNode;
4859
+ }
4735
4860
  class NodeInjector {
4736
4861
  constructor(_tNode, _lView) {
4737
4862
  this._tNode = _tNode;
@@ -4992,10 +5117,10 @@ const emitDistinctChangesOnlyDefaultValue = true;
4992
5117
  /**
4993
5118
  * Base class for query metadata.
4994
5119
  *
4995
- * @see {@link ContentChildren}.
4996
- * @see {@link ContentChild}.
4997
- * @see {@link ViewChildren}.
4998
- * @see {@link ViewChild}.
5120
+ * @see {@link ContentChildren}
5121
+ * @see {@link ContentChild}
5122
+ * @see {@link ViewChildren}
5123
+ * @see {@link ViewChild}
4999
5124
  *
5000
5125
  * @publicApi
5001
5126
  */
@@ -8827,6 +8952,9 @@ function internalImportProvidersFrom(checkForStandaloneCmp, ...sources) {
8827
8952
  const providersOut = [];
8828
8953
  const dedup = new Set(); // already seen types
8829
8954
  let injectorTypesWithProviders;
8955
+ const collectProviders = (provider) => {
8956
+ providersOut.push(provider);
8957
+ };
8830
8958
  deepForEach(sources, source => {
8831
8959
  if ((typeof ngDevMode === 'undefined' || ngDevMode) && checkForStandaloneCmp) {
8832
8960
  const cmpDef = getComponentDef(source);
@@ -8836,14 +8964,14 @@ function internalImportProvidersFrom(checkForStandaloneCmp, ...sources) {
8836
8964
  }
8837
8965
  // Narrow `source` to access the internal type analogue for `ModuleWithProviders`.
8838
8966
  const internalSource = source;
8839
- if (walkProviderTree(internalSource, providersOut, [], dedup)) {
8967
+ if (walkProviderTree(internalSource, collectProviders, [], dedup)) {
8840
8968
  injectorTypesWithProviders ||= [];
8841
8969
  injectorTypesWithProviders.push(internalSource);
8842
8970
  }
8843
8971
  });
8844
8972
  // Collect all providers from `ModuleWithProviders` types.
8845
8973
  if (injectorTypesWithProviders !== undefined) {
8846
- processInjectorTypesWithProviders(injectorTypesWithProviders, providersOut);
8974
+ processInjectorTypesWithProviders(injectorTypesWithProviders, collectProviders);
8847
8975
  }
8848
8976
  return providersOut;
8849
8977
  }
@@ -8851,12 +8979,12 @@ function internalImportProvidersFrom(checkForStandaloneCmp, ...sources) {
8851
8979
  * Collects all providers from the list of `ModuleWithProviders` and appends them to the provided
8852
8980
  * array.
8853
8981
  */
8854
- function processInjectorTypesWithProviders(typesWithProviders, providersOut) {
8982
+ function processInjectorTypesWithProviders(typesWithProviders, visitor) {
8855
8983
  for (let i = 0; i < typesWithProviders.length; i++) {
8856
8984
  const { ngModule, providers } = typesWithProviders[i];
8857
8985
  deepForEachProvider(providers, provider => {
8858
8986
  ngDevMode && validateProvider(provider, providers || EMPTY_ARRAY, ngModule);
8859
- providersOut.push(provider);
8987
+ visitor(provider, ngModule);
8860
8988
  });
8861
8989
  }
8862
8990
  }
@@ -8869,7 +8997,7 @@ function processInjectorTypesWithProviders(typesWithProviders, providersOut) {
8869
8997
  * to be processed. This allows us to process providers of injector types after all imports of
8870
8998
  * an injector definition are processed. (following View Engine semantics: see FW-1349)
8871
8999
  */
8872
- function walkProviderTree(container, providersOut, parents, dedup) {
9000
+ function walkProviderTree(container, visitor, parents, dedup) {
8873
9001
  container = resolveForwardRef(container);
8874
9002
  if (!container)
8875
9003
  return false;
@@ -8917,7 +9045,7 @@ function walkProviderTree(container, providersOut, parents, dedup) {
8917
9045
  if (cmpDef.dependencies) {
8918
9046
  const deps = typeof cmpDef.dependencies === 'function' ? cmpDef.dependencies() : cmpDef.dependencies;
8919
9047
  for (const dep of deps) {
8920
- walkProviderTree(dep, providersOut, parents, dedup);
9048
+ walkProviderTree(dep, visitor, parents, dedup);
8921
9049
  }
8922
9050
  }
8923
9051
  }
@@ -8932,7 +9060,7 @@ function walkProviderTree(container, providersOut, parents, dedup) {
8932
9060
  let importTypesWithProviders;
8933
9061
  try {
8934
9062
  deepForEach(injDef.imports, imported => {
8935
- if (walkProviderTree(imported, providersOut, parents, dedup)) {
9063
+ if (walkProviderTree(imported, visitor, parents, dedup)) {
8936
9064
  importTypesWithProviders ||= [];
8937
9065
  // If the processed import is an injector type with providers, we store it in the
8938
9066
  // list of import types with providers, so that we can process those afterwards.
@@ -8948,7 +9076,7 @@ function walkProviderTree(container, providersOut, parents, dedup) {
8948
9076
  // after all imported modules are processed. This is similar to how View Engine
8949
9077
  // processes/merges module imports in the metadata resolver. See: FW-1349.
8950
9078
  if (importTypesWithProviders !== undefined) {
8951
- processInjectorTypesWithProviders(importTypesWithProviders, providersOut);
9079
+ processInjectorTypesWithProviders(importTypesWithProviders, visitor);
8952
9080
  }
8953
9081
  }
8954
9082
  if (!isDuplicate) {
@@ -8958,14 +9086,12 @@ function walkProviderTree(container, providersOut, parents, dedup) {
8958
9086
  // Append extra providers to make more info available for consumers (to retrieve an injector
8959
9087
  // type), as well as internally (to calculate an injection scope correctly and eagerly
8960
9088
  // instantiate a `defType` when an injector is created).
8961
- providersOut.push(
8962
9089
  // Provider to create `defType` using its factory.
8963
- { provide: defType, useFactory: factory, deps: EMPTY_ARRAY },
9090
+ visitor({ provide: defType, useFactory: factory, deps: EMPTY_ARRAY }, defType);
8964
9091
  // Make this `defType` available to an internal logic that calculates injector scope.
8965
- { provide: INJECTOR_DEF_TYPES, useValue: defType, multi: true },
8966
- // Provider to eagerly instantiate `defType` via `ENVIRONMENT_INITIALIZER`.
8967
- { provide: ENVIRONMENT_INITIALIZER, useValue: () => ɵɵinject(defType), multi: true } //
8968
- );
9092
+ visitor({ provide: INJECTOR_DEF_TYPES, useValue: defType, multi: true }, defType);
9093
+ // Provider to eagerly instantiate `defType` via `INJECTOR_INITIALIZER`.
9094
+ visitor({ provide: ENVIRONMENT_INITIALIZER, useValue: () => ɵɵinject(defType), multi: true }, defType);
8969
9095
  }
8970
9096
  // Next, include providers listed on the definition itself.
8971
9097
  const defProviders = injDef.providers;
@@ -8973,7 +9099,7 @@ function walkProviderTree(container, providersOut, parents, dedup) {
8973
9099
  const injectorType = container;
8974
9100
  deepForEachProvider(defProviders, provider => {
8975
9101
  ngDevMode && validateProvider(provider, defProviders, injectorType);
8976
- providersOut.push(provider);
9102
+ visitor(provider, injectorType);
8977
9103
  });
8978
9104
  }
8979
9105
  }
@@ -9047,12 +9173,12 @@ const CIRCULAR = {};
9047
9173
  /**
9048
9174
  * A lazily initialized NullInjector.
9049
9175
  */
9050
- let NULL_INJECTOR$1 = undefined;
9176
+ let NULL_INJECTOR = undefined;
9051
9177
  function getNullInjector() {
9052
- if (NULL_INJECTOR$1 === undefined) {
9053
- NULL_INJECTOR$1 = new NullInjector();
9178
+ if (NULL_INJECTOR === undefined) {
9179
+ NULL_INJECTOR = new NullInjector();
9054
9180
  }
9055
- return NULL_INJECTOR$1;
9181
+ return NULL_INJECTOR;
9056
9182
  }
9057
9183
  /**
9058
9184
  * An `Injector` that's part of the environment injector hierarchy, which exists outside of the
@@ -9140,12 +9266,17 @@ class R3Injector extends EnvironmentInjector {
9140
9266
  this.assertNotDestroyed();
9141
9267
  const previousInjector = setCurrentInjector(this);
9142
9268
  const previousInjectImplementation = setInjectImplementation(undefined);
9269
+ let prevInjectContext;
9270
+ if (ngDevMode) {
9271
+ prevInjectContext = setInjectorProfilerContext({ injector: this, token: null });
9272
+ }
9143
9273
  try {
9144
9274
  return fn();
9145
9275
  }
9146
9276
  finally {
9147
9277
  setCurrentInjector(previousInjector);
9148
9278
  setInjectImplementation(previousInjectImplementation);
9279
+ ngDevMode && setInjectorProfilerContext(prevInjectContext);
9149
9280
  }
9150
9281
  }
9151
9282
  get(token, notFoundValue = THROW_IF_NOT_FOUND, flags = InjectFlags.Default) {
@@ -9155,6 +9286,10 @@ class R3Injector extends EnvironmentInjector {
9155
9286
  }
9156
9287
  flags = convertToBitFlags(flags);
9157
9288
  // Set the injection context.
9289
+ let prevInjectContext;
9290
+ if (ngDevMode) {
9291
+ prevInjectContext = setInjectorProfilerContext({ injector: this, token: token });
9292
+ }
9158
9293
  const previousInjector = setCurrentInjector(this);
9159
9294
  const previousInjectImplementation = setInjectImplementation(undefined);
9160
9295
  try {
@@ -9212,12 +9347,17 @@ class R3Injector extends EnvironmentInjector {
9212
9347
  // Lastly, restore the previous injection context.
9213
9348
  setInjectImplementation(previousInjectImplementation);
9214
9349
  setCurrentInjector(previousInjector);
9350
+ ngDevMode && setInjectorProfilerContext(prevInjectContext);
9215
9351
  }
9216
9352
  }
9217
9353
  /** @internal */
9218
9354
  resolveInjectorInitializers() {
9219
9355
  const previousInjector = setCurrentInjector(this);
9220
9356
  const previousInjectImplementation = setInjectImplementation(undefined);
9357
+ let prevInjectContext;
9358
+ if (ngDevMode) {
9359
+ prevInjectContext = setInjectorProfilerContext({ injector: this, token: null });
9360
+ }
9221
9361
  try {
9222
9362
  const initializers = this.get(ENVIRONMENT_INITIALIZER.multi, EMPTY_ARRAY, InjectFlags.Self);
9223
9363
  if (ngDevMode && !Array.isArray(initializers)) {
@@ -9233,6 +9373,7 @@ class R3Injector extends EnvironmentInjector {
9233
9373
  finally {
9234
9374
  setCurrentInjector(previousInjector);
9235
9375
  setInjectImplementation(previousInjectImplementation);
9376
+ ngDevMode && setInjectorProfilerContext(prevInjectContext);
9236
9377
  }
9237
9378
  }
9238
9379
  toString() {
@@ -9258,6 +9399,17 @@ class R3Injector extends EnvironmentInjector {
9258
9399
  let token = isTypeProvider(provider) ? provider : resolveForwardRef(provider && provider.provide);
9259
9400
  // Construct a `Record` for the provider.
9260
9401
  const record = providerToRecord(provider);
9402
+ if (ngDevMode) {
9403
+ runInInjectorProfilerContext(this, token, () => {
9404
+ // Emit InjectorProfilerEventType.Create if provider is a value provider because
9405
+ // these are the only providers that do not go through the value hydration logic
9406
+ // where this event would normally be emitted from.
9407
+ if (isValueProvider(provider)) {
9408
+ emitInstanceCreatedByInjectorEvent(provider.useValue);
9409
+ }
9410
+ emitProviderConfiguredEvent(provider);
9411
+ });
9412
+ }
9261
9413
  if (!isTypeProvider(provider) && provider.multi === true) {
9262
9414
  // If the provider indicates that it's a multi-provider, process it specially.
9263
9415
  // First check whether it's been defined already.
@@ -9290,7 +9442,15 @@ class R3Injector extends EnvironmentInjector {
9290
9442
  }
9291
9443
  else if (record.value === NOT_YET) {
9292
9444
  record.value = CIRCULAR;
9293
- record.value = record.factory();
9445
+ if (ngDevMode) {
9446
+ runInInjectorProfilerContext(this, token, () => {
9447
+ record.value = record.factory();
9448
+ emitInstanceCreatedByInjectorEvent(record.value);
9449
+ });
9450
+ }
9451
+ else {
9452
+ record.value = record.factory();
9453
+ }
9294
9454
  }
9295
9455
  if (typeof record.value === 'object' && record.value && hasOnDestroy(record.value)) {
9296
9456
  this._ngOnDestroyHooks.add(record.value);
@@ -10092,7 +10252,7 @@ class Version {
10092
10252
  /**
10093
10253
  * @publicApi
10094
10254
  */
10095
- const VERSION = new Version('16.2.0-next.3');
10255
+ const VERSION = new Version('16.2.0-rc.0');
10096
10256
 
10097
10257
  // This default value is when checking the hierarchy for a token.
10098
10258
  //
@@ -10114,136 +10274,296 @@ const VERSION = new Version('16.2.0-next.3');
10114
10274
  const NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR = {};
10115
10275
 
10116
10276
  /**
10117
- * Marks current view and all ancestors dirty.
10277
+ * Runs the given function in the [context](guide/dependency-injection-context) of the given
10278
+ * `Injector`.
10118
10279
  *
10119
- * Returns the root view because it is found as a byproduct of marking the view tree
10120
- * dirty, and can be used by methods that consume markViewDirty() to easily schedule
10121
- * change detection. Otherwise, such methods would need to traverse up the view tree
10122
- * an additional time to get the root view and schedule a tick on it.
10280
+ * Within the function's stack frame, [`inject`](api/core/inject) can be used to inject dependencies
10281
+ * from the given `Injector`. Note that `inject` is only usable synchronously, and cannot be used in
10282
+ * any asynchronous callbacks or after any `await` points.
10123
10283
  *
10124
- * @param lView The starting LView to mark dirty
10125
- * @returns the root LView
10284
+ * @param injector the injector which will satisfy calls to [`inject`](api/core/inject) while `fn`
10285
+ * is executing
10286
+ * @param fn the closure to be run in the context of `injector`
10287
+ * @returns the return value of the function, if any
10288
+ * @publicApi
10126
10289
  */
10127
- function markViewDirty(lView) {
10128
- while (lView) {
10129
- lView[FLAGS] |= 64 /* LViewFlags.Dirty */;
10130
- const parent = getLViewParent(lView);
10131
- // Stop traversing up as soon as you find a root view that wasn't attached to any container
10132
- if (isRootView(lView) && !parent) {
10133
- return lView;
10134
- }
10135
- // continue otherwise
10136
- lView = parent;
10290
+ function runInInjectionContext(injector, fn) {
10291
+ if (injector instanceof R3Injector) {
10292
+ injector.assertNotDestroyed();
10293
+ }
10294
+ let prevInjectorProfilerContext;
10295
+ if (ngDevMode) {
10296
+ prevInjectorProfilerContext = setInjectorProfilerContext({ injector, token: null });
10297
+ }
10298
+ const prevInjector = setCurrentInjector(injector);
10299
+ const previousInjectImplementation = setInjectImplementation(undefined);
10300
+ try {
10301
+ return fn();
10302
+ }
10303
+ finally {
10304
+ setCurrentInjector(prevInjector);
10305
+ ngDevMode && setInjectorProfilerContext(prevInjectorProfilerContext);
10306
+ setInjectImplementation(previousInjectImplementation);
10137
10307
  }
10138
- return null;
10139
- }
10140
-
10141
- const ERROR_ORIGINAL_ERROR = 'ngOriginalError';
10142
- function wrappedError(message, originalError) {
10143
- const msg = `${message} caused by: ${originalError instanceof Error ? originalError.message : originalError}`;
10144
- const error = Error(msg);
10145
- error[ERROR_ORIGINAL_ERROR] = originalError;
10146
- return error;
10147
- }
10148
- function getOriginalError(error) {
10149
- return error[ERROR_ORIGINAL_ERROR];
10150
10308
  }
10151
-
10152
10309
  /**
10153
- * Provides a hook for centralized exception handling.
10154
- *
10155
- * The default implementation of `ErrorHandler` prints error messages to the `console`. To
10156
- * intercept error handling, write a custom exception handler that replaces this default as
10157
- * appropriate for your app.
10158
- *
10159
- * @usageNotes
10160
- * ### Example
10161
- *
10162
- * ```
10163
- * class MyErrorHandler implements ErrorHandler {
10164
- * handleError(error) {
10165
- * // do something with the exception
10166
- * }
10167
- * }
10310
+ * Asserts that the current stack frame is within an [injection
10311
+ * context](guide/dependency-injection-context) and has access to `inject`.
10168
10312
  *
10169
- * @NgModule({
10170
- * providers: [{provide: ErrorHandler, useClass: MyErrorHandler}]
10171
- * })
10172
- * class MyModule {}
10173
- * ```
10313
+ * @param debugFn a reference to the function making the assertion (used for the error message).
10174
10314
  *
10175
10315
  * @publicApi
10176
10316
  */
10177
- class ErrorHandler {
10178
- constructor() {
10179
- /**
10180
- * @internal
10181
- */
10182
- this._console = console;
10183
- }
10184
- handleError(error) {
10185
- const originalError = this._findOriginalError(error);
10186
- this._console.error('ERROR', error);
10187
- if (originalError) {
10188
- this._console.error('ORIGINAL ERROR', originalError);
10189
- }
10190
- }
10191
- /** @internal */
10192
- _findOriginalError(error) {
10193
- let e = error && getOriginalError(error);
10194
- while (e && getOriginalError(e)) {
10195
- e = getOriginalError(e);
10196
- }
10197
- return e || null;
10317
+ function assertInInjectionContext(debugFn) {
10318
+ // Taking a `Function` instead of a string name here prevents the unminified name of the function
10319
+ // from being retained in the bundle regardless of minification.
10320
+ if (!getInjectImplementation() && !getCurrentInjector()) {
10321
+ throw new RuntimeError(-203 /* RuntimeErrorCode.MISSING_INJECTION_CONTEXT */, ngDevMode &&
10322
+ (debugFn.name +
10323
+ '() can only be used within an injection context such as a constructor, a factory function, a field initializer, or a function used with `runInInjectionContext`'));
10198
10324
  }
10199
10325
  }
10200
10326
 
10201
10327
  /**
10202
- * Internal token that specifies whether DOM reuse logic
10203
- * during hydration is enabled.
10328
+ * A mapping of the @angular/core API surface used in generated expressions to the actual symbols.
10329
+ *
10330
+ * This should be kept up to date with the public exports of @angular/core.
10204
10331
  */
10205
- const IS_HYDRATION_DOM_REUSE_ENABLED = new InjectionToken((typeof ngDevMode === 'undefined' || !!ngDevMode) ? 'IS_HYDRATION_DOM_REUSE_ENABLED' : '');
10206
- // By default (in client rendering mode), we remove all the contents
10207
- // of the host element and render an application after that.
10208
- const PRESERVE_HOST_CONTENT_DEFAULT = false;
10332
+ const angularCoreDiEnv = {
10333
+ 'ɵɵdefineInjectable': ɵɵdefineInjectable,
10334
+ 'ɵɵdefineInjector': ɵɵdefineInjector,
10335
+ 'ɵɵinject': ɵɵinject,
10336
+ 'ɵɵinvalidFactoryDep': ɵɵinvalidFactoryDep,
10337
+ 'resolveForwardRef': resolveForwardRef,
10338
+ };
10339
+
10209
10340
  /**
10210
- * Internal token that indicates whether host element content should be
10211
- * retained during the bootstrap.
10341
+ * Compile an Angular injectable according to its `Injectable` metadata, and patch the resulting
10342
+ * injectable def (`ɵprov`) onto the injectable type.
10212
10343
  */
10213
- const PRESERVE_HOST_CONTENT = new InjectionToken((typeof ngDevMode === 'undefined' || !!ngDevMode) ? 'PRESERVE_HOST_CONTENT' : '', {
10214
- providedIn: 'root',
10215
- factory: () => PRESERVE_HOST_CONTENT_DEFAULT,
10216
- });
10217
-
10218
- function normalizeDebugBindingName(name) {
10219
- // Attribute names with `$` (eg `x-y$`) are valid per spec, but unsupported by some browsers
10220
- name = camelCaseToDashCase(name.replace(/[$@]/g, '_'));
10221
- return `ng-reflect-${name}`;
10222
- }
10223
- const CAMEL_CASE_REGEXP = /([A-Z])/g;
10224
- function camelCaseToDashCase(input) {
10225
- return input.replace(CAMEL_CASE_REGEXP, (...m) => '-' + m[1].toLowerCase());
10226
- }
10227
- function normalizeDebugBindingValue(value) {
10228
- try {
10229
- // Limit the size of the value as otherwise the DOM just gets polluted.
10230
- return value != null ? value.toString().slice(0, 30) : value;
10344
+ function compileInjectable(type, meta) {
10345
+ let ngInjectableDef = null;
10346
+ let ngFactoryDef = null;
10347
+ // if NG_PROV_DEF is already defined on this class then don't overwrite it
10348
+ if (!type.hasOwnProperty(NG_PROV_DEF)) {
10349
+ Object.defineProperty(type, NG_PROV_DEF, {
10350
+ get: () => {
10351
+ if (ngInjectableDef === null) {
10352
+ const compiler = getCompilerFacade({ usage: 0 /* JitCompilerUsage.Decorator */, kind: 'injectable', type });
10353
+ ngInjectableDef = compiler.compileInjectable(angularCoreDiEnv, `ng:///${type.name}/ɵprov.js`, getInjectableMetadata(type, meta));
10354
+ }
10355
+ return ngInjectableDef;
10356
+ },
10357
+ });
10231
10358
  }
10232
- catch (e) {
10233
- return '[ERROR] Exception while trying to serialize the value';
10359
+ // if NG_FACTORY_DEF is already defined on this class then don't overwrite it
10360
+ if (!type.hasOwnProperty(NG_FACTORY_DEF)) {
10361
+ Object.defineProperty(type, NG_FACTORY_DEF, {
10362
+ get: () => {
10363
+ if (ngFactoryDef === null) {
10364
+ const compiler = getCompilerFacade({ usage: 0 /* JitCompilerUsage.Decorator */, kind: 'injectable', type });
10365
+ ngFactoryDef = compiler.compileFactory(angularCoreDiEnv, `ng:///${type.name}/ɵfac.js`, {
10366
+ name: type.name,
10367
+ type,
10368
+ typeArgumentCount: 0,
10369
+ deps: reflectDependencies(type),
10370
+ target: compiler.FactoryTarget.Injectable
10371
+ });
10372
+ }
10373
+ return ngFactoryDef;
10374
+ },
10375
+ // Leave this configurable so that the factories from directives or pipes can take precedence.
10376
+ configurable: true
10377
+ });
10234
10378
  }
10235
10379
  }
10236
-
10237
- /**
10238
- *
10239
- * @codeGenApi
10240
- */
10241
- function ɵɵresolveWindow(element) {
10242
- return element.ownerDocument.defaultView;
10380
+ const USE_VALUE = getClosureSafeProperty({ provide: String, useValue: getClosureSafeProperty });
10381
+ function isUseClassProvider(meta) {
10382
+ return meta.useClass !== undefined;
10243
10383
  }
10244
- /**
10245
- *
10246
- * @codeGenApi
10384
+ function isUseValueProvider(meta) {
10385
+ return USE_VALUE in meta;
10386
+ }
10387
+ function isUseFactoryProvider(meta) {
10388
+ return meta.useFactory !== undefined;
10389
+ }
10390
+ function isUseExistingProvider(meta) {
10391
+ return meta.useExisting !== undefined;
10392
+ }
10393
+ function getInjectableMetadata(type, srcMeta) {
10394
+ // Allow the compilation of a class with a `@Injectable()` decorator without parameters
10395
+ const meta = srcMeta || { providedIn: null };
10396
+ const compilerMeta = {
10397
+ name: type.name,
10398
+ type: type,
10399
+ typeArgumentCount: 0,
10400
+ providedIn: meta.providedIn,
10401
+ };
10402
+ if ((isUseClassProvider(meta) || isUseFactoryProvider(meta)) && meta.deps !== undefined) {
10403
+ compilerMeta.deps = convertDependencies(meta.deps);
10404
+ }
10405
+ // Check to see if the user explicitly provided a `useXxxx` property.
10406
+ if (isUseClassProvider(meta)) {
10407
+ compilerMeta.useClass = meta.useClass;
10408
+ }
10409
+ else if (isUseValueProvider(meta)) {
10410
+ compilerMeta.useValue = meta.useValue;
10411
+ }
10412
+ else if (isUseFactoryProvider(meta)) {
10413
+ compilerMeta.useFactory = meta.useFactory;
10414
+ }
10415
+ else if (isUseExistingProvider(meta)) {
10416
+ compilerMeta.useExisting = meta.useExisting;
10417
+ }
10418
+ return compilerMeta;
10419
+ }
10420
+
10421
+ /**
10422
+ * Injectable decorator and metadata.
10423
+ *
10424
+ * @Annotation
10425
+ * @publicApi
10426
+ */
10427
+ const Injectable = makeDecorator('Injectable', undefined, undefined, undefined, (type, meta) => compileInjectable(type, meta));
10428
+
10429
+ /**
10430
+ * Create a new `Injector` which is configured using a `defType` of `InjectorType<any>`s.
10431
+ */
10432
+ function createInjector(defType, parent = null, additionalProviders = null, name) {
10433
+ const injector = createInjectorWithoutInjectorInstances(defType, parent, additionalProviders, name);
10434
+ injector.resolveInjectorInitializers();
10435
+ return injector;
10436
+ }
10437
+ /**
10438
+ * Creates a new injector without eagerly resolving its injector types. Can be used in places
10439
+ * where resolving the injector types immediately can lead to an infinite loop. The injector types
10440
+ * should be resolved at a later point by calling `_resolveInjectorDefTypes`.
10441
+ */
10442
+ function createInjectorWithoutInjectorInstances(defType, parent = null, additionalProviders = null, name, scopes = new Set()) {
10443
+ const providers = [
10444
+ additionalProviders || EMPTY_ARRAY,
10445
+ importProvidersFrom(defType),
10446
+ ];
10447
+ name = name || (typeof defType === 'object' ? undefined : stringify(defType));
10448
+ return new R3Injector(providers, parent || getNullInjector(), name || null, scopes);
10449
+ }
10450
+
10451
+ /**
10452
+ * Concrete injectors implement this interface. Injectors are configured
10453
+ * with [providers](guide/glossary#provider) that associate
10454
+ * dependencies of various types with [injection tokens](guide/glossary#di-token).
10455
+ *
10456
+ * @see ["DI Providers"](guide/dependency-injection-providers).
10457
+ * @see {@link StaticProvider}
10458
+ *
10459
+ * @usageNotes
10460
+ *
10461
+ * The following example creates a service injector instance.
10462
+ *
10463
+ * {@example core/di/ts/provider_spec.ts region='ConstructorProvider'}
10464
+ *
10465
+ * ### Usage example
10466
+ *
10467
+ * {@example core/di/ts/injector_spec.ts region='Injector'}
10468
+ *
10469
+ * `Injector` returns itself when given `Injector` as a token:
10470
+ *
10471
+ * {@example core/di/ts/injector_spec.ts region='injectInjector'}
10472
+ *
10473
+ * @publicApi
10474
+ */
10475
+ class Injector {
10476
+ static { this.THROW_IF_NOT_FOUND = THROW_IF_NOT_FOUND; }
10477
+ static { this.NULL = ( /* @__PURE__ */new NullInjector()); }
10478
+ static create(options, parent) {
10479
+ if (Array.isArray(options)) {
10480
+ return createInjector({ name: '' }, parent, options, '');
10481
+ }
10482
+ else {
10483
+ const name = options.name ?? '';
10484
+ return createInjector({ name }, options.parent, options.providers, name);
10485
+ }
10486
+ }
10487
+ /** @nocollapse */
10488
+ static { this.ɵprov = ɵɵdefineInjectable({
10489
+ token: Injector,
10490
+ providedIn: 'any',
10491
+ factory: () => ɵɵinject(INJECTOR),
10492
+ }); }
10493
+ /**
10494
+ * @internal
10495
+ * @nocollapse
10496
+ */
10497
+ static { this.__NG_ELEMENT_ID__ = -1 /* InjectorMarkers.Injector */; }
10498
+ }
10499
+
10500
+ /**
10501
+ * @module
10502
+ * @description
10503
+ * The `di` module provides dependency injection container services.
10504
+ */
10505
+
10506
+ /**
10507
+ * This file should not be necessary because node resolution should just default to `./di/index`!
10508
+ *
10509
+ * However it does not seem to work and it breaks:
10510
+ * - //packages/animations/browser/test:test_web_chromium-local
10511
+ * - //packages/compiler-cli/test:extract_i18n
10512
+ * - //packages/compiler-cli/test:ngc
10513
+ * - //packages/compiler-cli/test:perform_watch
10514
+ * - //packages/compiler-cli/test/diagnostics:check_types
10515
+ * - //packages/compiler-cli/test/transformers:test
10516
+ * - //packages/compiler/test:test
10517
+ * - //tools/public_api_guard:core_api
10518
+ *
10519
+ * Remove this file once the above is solved or wait until `ngc` is deleted and then it should be
10520
+ * safe to delete this file.
10521
+ */
10522
+
10523
+ /**
10524
+ * `DestroyRef` lets you set callbacks to run for any cleanup or destruction behavior.
10525
+ * The scope of this destruction depends on where `DestroyRef` is injected. If `DestroyRef`
10526
+ * is injected in a component or directive, the callbacks run when that component or
10527
+ * directive is destroyed. Otherwise the callbacks run when a corresponding injector is destroyed.
10528
+ *
10529
+ * @publicApi
10530
+ */
10531
+ class DestroyRef {
10532
+ /**
10533
+ * @internal
10534
+ * @nocollapse
10535
+ */
10536
+ static { this.__NG_ELEMENT_ID__ = injectDestroyRef; }
10537
+ /**
10538
+ * @internal
10539
+ * @nocollapse
10540
+ */
10541
+ static { this.__NG_ENV_ID__ = (injector) => injector; }
10542
+ }
10543
+ class NodeInjectorDestroyRef extends DestroyRef {
10544
+ constructor(_lView) {
10545
+ super();
10546
+ this._lView = _lView;
10547
+ }
10548
+ onDestroy(callback) {
10549
+ storeLViewOnDestroy(this._lView, callback);
10550
+ return () => removeLViewOnDestroy(this._lView, callback);
10551
+ }
10552
+ }
10553
+ function injectDestroyRef() {
10554
+ return new NodeInjectorDestroyRef(getLView());
10555
+ }
10556
+
10557
+ /**
10558
+ *
10559
+ * @codeGenApi
10560
+ */
10561
+ function ɵɵresolveWindow(element) {
10562
+ return element.ownerDocument.defaultView;
10563
+ }
10564
+ /**
10565
+ *
10566
+ * @codeGenApi
10247
10567
  */
10248
10568
  function ɵɵresolveDocument(element) {
10249
10569
  return element.ownerDocument;
@@ -10277,8 +10597,335 @@ function maybeUnwrapFn(value) {
10277
10597
  if (value instanceof Function) {
10278
10598
  return value();
10279
10599
  }
10280
- else {
10281
- return value;
10600
+ else {
10601
+ return value;
10602
+ }
10603
+ }
10604
+ /**
10605
+ * Detects whether the code is invoked in a browser.
10606
+ * Later on, this check should be replaced with a tree-shakable
10607
+ * flag (e.g. `!isServer`).
10608
+ */
10609
+ function isPlatformBrowser(injector) {
10610
+ return (injector ?? inject(Injector)).get(PLATFORM_ID) === 'browser';
10611
+ }
10612
+
10613
+ /**
10614
+ * Register a callback to be invoked each time the application
10615
+ * finishes rendering.
10616
+ *
10617
+ * Note that the callback will run
10618
+ * - in the order it was registered
10619
+ * - once per render
10620
+ * - on browser platforms only
10621
+ *
10622
+ * <div class="alert is-important">
10623
+ *
10624
+ * Components are not guaranteed to be [hydrated](guide/hydration) before the callback runs.
10625
+ * You must use caution when directly reading or writing the DOM and layout.
10626
+ *
10627
+ * </div>
10628
+ *
10629
+ * @param callback A callback function to register
10630
+ *
10631
+ * @usageNotes
10632
+ *
10633
+ * Use `afterRender` to read or write the DOM after each render.
10634
+ *
10635
+ * ### Example
10636
+ * ```ts
10637
+ * @Component({
10638
+ * selector: 'my-cmp',
10639
+ * template: `<span #content>{{ ... }}</span>`,
10640
+ * })
10641
+ * export class MyComponent {
10642
+ * @ViewChild('content') contentRef: ElementRef;
10643
+ *
10644
+ * constructor() {
10645
+ * afterRender(() => {
10646
+ * console.log('content height: ' + this.contentRef.nativeElement.scrollHeight);
10647
+ * });
10648
+ * }
10649
+ * }
10650
+ * ```
10651
+ *
10652
+ * @developerPreview
10653
+ */
10654
+ function afterRender(callback, options) {
10655
+ !options && assertInInjectionContext(afterRender);
10656
+ const injector = options?.injector ?? inject(Injector);
10657
+ if (!isPlatformBrowser(injector)) {
10658
+ return { destroy() { } };
10659
+ }
10660
+ let destroy;
10661
+ const unregisterFn = injector.get(DestroyRef).onDestroy(() => destroy?.());
10662
+ const manager = injector.get(AfterRenderEventManager);
10663
+ const instance = new AfterRenderCallback(callback);
10664
+ destroy = () => {
10665
+ manager.unregister(instance);
10666
+ unregisterFn();
10667
+ };
10668
+ manager.register(instance);
10669
+ return { destroy };
10670
+ }
10671
+ /**
10672
+ * Register a callback to be invoked the next time the application
10673
+ * finishes rendering.
10674
+ *
10675
+ * Note that the callback will run
10676
+ * - in the order it was registered
10677
+ * - on browser platforms only
10678
+ *
10679
+ * <div class="alert is-important">
10680
+ *
10681
+ * Components are not guaranteed to be [hydrated](guide/hydration) before the callback runs.
10682
+ * You must use caution when directly reading or writing the DOM and layout.
10683
+ *
10684
+ * </div>
10685
+ *
10686
+ * @param callback A callback function to register
10687
+ *
10688
+ * @usageNotes
10689
+ *
10690
+ * Use `afterNextRender` to read or write the DOM once,
10691
+ * for example to initialize a non-Angular library.
10692
+ *
10693
+ * ### Example
10694
+ * ```ts
10695
+ * @Component({
10696
+ * selector: 'my-chart-cmp',
10697
+ * template: `<div #chart>{{ ... }}</div>`,
10698
+ * })
10699
+ * export class MyChartCmp {
10700
+ * @ViewChild('chart') chartRef: ElementRef;
10701
+ * chart: MyChart|null;
10702
+ *
10703
+ * constructor() {
10704
+ * afterNextRender(() => {
10705
+ * this.chart = new MyChart(this.chartRef.nativeElement);
10706
+ * });
10707
+ * }
10708
+ * }
10709
+ * ```
10710
+ *
10711
+ * @developerPreview
10712
+ */
10713
+ function afterNextRender(callback, options) {
10714
+ !options && assertInInjectionContext(afterNextRender);
10715
+ const injector = options?.injector ?? inject(Injector);
10716
+ if (!isPlatformBrowser(injector)) {
10717
+ return { destroy() { } };
10718
+ }
10719
+ let destroy;
10720
+ const unregisterFn = injector.get(DestroyRef).onDestroy(() => destroy?.());
10721
+ const manager = injector.get(AfterRenderEventManager);
10722
+ const instance = new AfterRenderCallback(() => {
10723
+ destroy?.();
10724
+ callback();
10725
+ });
10726
+ destroy = () => {
10727
+ manager.unregister(instance);
10728
+ unregisterFn();
10729
+ };
10730
+ manager.register(instance);
10731
+ return { destroy };
10732
+ }
10733
+ /**
10734
+ * A wrapper around a function to be used as an after render callback.
10735
+ * @private
10736
+ */
10737
+ class AfterRenderCallback {
10738
+ constructor(callback) {
10739
+ this.callback = callback;
10740
+ }
10741
+ invoke() {
10742
+ this.callback();
10743
+ }
10744
+ }
10745
+ /**
10746
+ * Implements `afterRender` and `afterNextRender` callback manager logic.
10747
+ */
10748
+ class AfterRenderEventManager {
10749
+ constructor() {
10750
+ this.callbacks = new Set();
10751
+ this.deferredCallbacks = new Set();
10752
+ this.renderDepth = 0;
10753
+ this.runningCallbacks = false;
10754
+ }
10755
+ /**
10756
+ * Mark the beginning of a render operation (i.e. CD cycle).
10757
+ * Throws if called from an `afterRender` callback.
10758
+ */
10759
+ begin() {
10760
+ if (this.runningCallbacks) {
10761
+ throw new RuntimeError(102 /* RuntimeErrorCode.RECURSIVE_APPLICATION_RENDER */, ngDevMode &&
10762
+ 'A new render operation began before the previous operation ended. ' +
10763
+ 'Did you trigger change detection from afterRender or afterNextRender?');
10764
+ }
10765
+ this.renderDepth++;
10766
+ }
10767
+ /**
10768
+ * Mark the end of a render operation. Registered callbacks
10769
+ * are invoked if there are no more pending operations.
10770
+ */
10771
+ end() {
10772
+ this.renderDepth--;
10773
+ if (this.renderDepth === 0) {
10774
+ try {
10775
+ this.runningCallbacks = true;
10776
+ for (const callback of this.callbacks) {
10777
+ callback.invoke();
10778
+ }
10779
+ }
10780
+ finally {
10781
+ this.runningCallbacks = false;
10782
+ for (const callback of this.deferredCallbacks) {
10783
+ this.callbacks.add(callback);
10784
+ }
10785
+ this.deferredCallbacks.clear();
10786
+ }
10787
+ }
10788
+ }
10789
+ register(callback) {
10790
+ // If we're currently running callbacks, new callbacks should be deferred
10791
+ // until the next render operation.
10792
+ const target = this.runningCallbacks ? this.deferredCallbacks : this.callbacks;
10793
+ target.add(callback);
10794
+ }
10795
+ unregister(callback) {
10796
+ this.callbacks.delete(callback);
10797
+ this.deferredCallbacks.delete(callback);
10798
+ }
10799
+ ngOnDestroy() {
10800
+ this.callbacks.clear();
10801
+ this.deferredCallbacks.clear();
10802
+ }
10803
+ /** @nocollapse */
10804
+ static { this.ɵprov = ɵɵdefineInjectable({
10805
+ token: AfterRenderEventManager,
10806
+ providedIn: 'root',
10807
+ factory: () => new AfterRenderEventManager(),
10808
+ }); }
10809
+ }
10810
+
10811
+ /**
10812
+ * Marks current view and all ancestors dirty.
10813
+ *
10814
+ * Returns the root view because it is found as a byproduct of marking the view tree
10815
+ * dirty, and can be used by methods that consume markViewDirty() to easily schedule
10816
+ * change detection. Otherwise, such methods would need to traverse up the view tree
10817
+ * an additional time to get the root view and schedule a tick on it.
10818
+ *
10819
+ * @param lView The starting LView to mark dirty
10820
+ * @returns the root LView
10821
+ */
10822
+ function markViewDirty(lView) {
10823
+ while (lView) {
10824
+ lView[FLAGS] |= 64 /* LViewFlags.Dirty */;
10825
+ const parent = getLViewParent(lView);
10826
+ // Stop traversing up as soon as you find a root view that wasn't attached to any container
10827
+ if (isRootView(lView) && !parent) {
10828
+ return lView;
10829
+ }
10830
+ // continue otherwise
10831
+ lView = parent;
10832
+ }
10833
+ return null;
10834
+ }
10835
+
10836
+ const ERROR_ORIGINAL_ERROR = 'ngOriginalError';
10837
+ function wrappedError(message, originalError) {
10838
+ const msg = `${message} caused by: ${originalError instanceof Error ? originalError.message : originalError}`;
10839
+ const error = Error(msg);
10840
+ error[ERROR_ORIGINAL_ERROR] = originalError;
10841
+ return error;
10842
+ }
10843
+ function getOriginalError(error) {
10844
+ return error[ERROR_ORIGINAL_ERROR];
10845
+ }
10846
+
10847
+ /**
10848
+ * Provides a hook for centralized exception handling.
10849
+ *
10850
+ * The default implementation of `ErrorHandler` prints error messages to the `console`. To
10851
+ * intercept error handling, write a custom exception handler that replaces this default as
10852
+ * appropriate for your app.
10853
+ *
10854
+ * @usageNotes
10855
+ * ### Example
10856
+ *
10857
+ * ```
10858
+ * class MyErrorHandler implements ErrorHandler {
10859
+ * handleError(error) {
10860
+ * // do something with the exception
10861
+ * }
10862
+ * }
10863
+ *
10864
+ * @NgModule({
10865
+ * providers: [{provide: ErrorHandler, useClass: MyErrorHandler}]
10866
+ * })
10867
+ * class MyModule {}
10868
+ * ```
10869
+ *
10870
+ * @publicApi
10871
+ */
10872
+ class ErrorHandler {
10873
+ constructor() {
10874
+ /**
10875
+ * @internal
10876
+ */
10877
+ this._console = console;
10878
+ }
10879
+ handleError(error) {
10880
+ const originalError = this._findOriginalError(error);
10881
+ this._console.error('ERROR', error);
10882
+ if (originalError) {
10883
+ this._console.error('ORIGINAL ERROR', originalError);
10884
+ }
10885
+ }
10886
+ /** @internal */
10887
+ _findOriginalError(error) {
10888
+ let e = error && getOriginalError(error);
10889
+ while (e && getOriginalError(e)) {
10890
+ e = getOriginalError(e);
10891
+ }
10892
+ return e || null;
10893
+ }
10894
+ }
10895
+
10896
+ /**
10897
+ * Internal token that specifies whether DOM reuse logic
10898
+ * during hydration is enabled.
10899
+ */
10900
+ const IS_HYDRATION_DOM_REUSE_ENABLED = new InjectionToken((typeof ngDevMode === 'undefined' || !!ngDevMode) ? 'IS_HYDRATION_DOM_REUSE_ENABLED' : '');
10901
+ // By default (in client rendering mode), we remove all the contents
10902
+ // of the host element and render an application after that.
10903
+ const PRESERVE_HOST_CONTENT_DEFAULT = false;
10904
+ /**
10905
+ * Internal token that indicates whether host element content should be
10906
+ * retained during the bootstrap.
10907
+ */
10908
+ const PRESERVE_HOST_CONTENT = new InjectionToken((typeof ngDevMode === 'undefined' || !!ngDevMode) ? 'PRESERVE_HOST_CONTENT' : '', {
10909
+ providedIn: 'root',
10910
+ factory: () => PRESERVE_HOST_CONTENT_DEFAULT,
10911
+ });
10912
+
10913
+ function normalizeDebugBindingName(name) {
10914
+ // Attribute names with `$` (eg `x-y$`) are valid per spec, but unsupported by some browsers
10915
+ name = camelCaseToDashCase(name.replace(/[$@]/g, '_'));
10916
+ return `ng-reflect-${name}`;
10917
+ }
10918
+ const CAMEL_CASE_REGEXP = /([A-Z])/g;
10919
+ function camelCaseToDashCase(input) {
10920
+ return input.replace(CAMEL_CASE_REGEXP, (...m) => '-' + m[1].toLowerCase());
10921
+ }
10922
+ function normalizeDebugBindingValue(value) {
10923
+ try {
10924
+ // Limit the size of the value as otherwise the DOM just gets polluted.
10925
+ return value != null ? value.toString().slice(0, 30) : value;
10926
+ }
10927
+ catch (e) {
10928
+ return '[ERROR] Exception while trying to serialize the value';
10282
10929
  }
10283
10930
  }
10284
10931
 
@@ -10511,253 +11158,9 @@ function selectIndexInternal(tView, lView, index, checkNoChangesMode) {
10511
11158
  // We must set the selected index *after* running the hooks, because hooks may have side-effects
10512
11159
  // that cause other template functions to run, thus updating the selected index, which is global
10513
11160
  // state. If we run `setSelectedIndex` *before* we run the hooks, in some cases the selected index
10514
- // will be altered by the time we leave the `ɵɵadvance` instruction.
10515
- setSelectedIndex(index);
10516
- }
10517
-
10518
- /**
10519
- * Runs the given function in the [context](guide/dependency-injection-context) of the given
10520
- * `Injector`.
10521
- *
10522
- * Within the function's stack frame, [`inject`](api/core/inject) can be used to inject dependencies
10523
- * from the given `Injector`. Note that `inject` is only usable synchronously, and cannot be used in
10524
- * any asynchronous callbacks or after any `await` points.
10525
- *
10526
- * @param injector the injector which will satisfy calls to [`inject`](api/core/inject) while `fn`
10527
- * is executing
10528
- * @param fn the closure to be run in the context of `injector`
10529
- * @returns the return value of the function, if any
10530
- * @publicApi
10531
- */
10532
- function runInInjectionContext(injector, fn) {
10533
- if (injector instanceof R3Injector) {
10534
- injector.assertNotDestroyed();
10535
- }
10536
- const prevInjector = setCurrentInjector(injector);
10537
- const previousInjectImplementation = setInjectImplementation(undefined);
10538
- try {
10539
- return fn();
10540
- }
10541
- finally {
10542
- setCurrentInjector(prevInjector);
10543
- setInjectImplementation(previousInjectImplementation);
10544
- }
10545
- }
10546
- /**
10547
- * Asserts that the current stack frame is within an [injection
10548
- * context](guide/dependency-injection-context) and has access to `inject`.
10549
- *
10550
- * @param debugFn a reference to the function making the assertion (used for the error message).
10551
- *
10552
- * @publicApi
10553
- */
10554
- function assertInInjectionContext(debugFn) {
10555
- // Taking a `Function` instead of a string name here prevents the unminified name of the function
10556
- // from being retained in the bundle regardless of minification.
10557
- if (!getInjectImplementation() && !getCurrentInjector()) {
10558
- throw new RuntimeError(-203 /* RuntimeErrorCode.MISSING_INJECTION_CONTEXT */, ngDevMode &&
10559
- (debugFn.name +
10560
- '() can only be used within an injection context such as a constructor, a factory function, a field initializer, or a function used with `runInInjectionContext`'));
10561
- }
10562
- }
10563
-
10564
- /**
10565
- * A mapping of the @angular/core API surface used in generated expressions to the actual symbols.
10566
- *
10567
- * This should be kept up to date with the public exports of @angular/core.
10568
- */
10569
- const angularCoreDiEnv = {
10570
- 'ɵɵdefineInjectable': ɵɵdefineInjectable,
10571
- 'ɵɵdefineInjector': ɵɵdefineInjector,
10572
- 'ɵɵinject': ɵɵinject,
10573
- 'ɵɵinvalidFactoryDep': ɵɵinvalidFactoryDep,
10574
- 'resolveForwardRef': resolveForwardRef,
10575
- };
10576
-
10577
- /**
10578
- * Compile an Angular injectable according to its `Injectable` metadata, and patch the resulting
10579
- * injectable def (`ɵprov`) onto the injectable type.
10580
- */
10581
- function compileInjectable(type, meta) {
10582
- let ngInjectableDef = null;
10583
- let ngFactoryDef = null;
10584
- // if NG_PROV_DEF is already defined on this class then don't overwrite it
10585
- if (!type.hasOwnProperty(NG_PROV_DEF)) {
10586
- Object.defineProperty(type, NG_PROV_DEF, {
10587
- get: () => {
10588
- if (ngInjectableDef === null) {
10589
- const compiler = getCompilerFacade({ usage: 0 /* JitCompilerUsage.Decorator */, kind: 'injectable', type });
10590
- ngInjectableDef = compiler.compileInjectable(angularCoreDiEnv, `ng:///${type.name}/ɵprov.js`, getInjectableMetadata(type, meta));
10591
- }
10592
- return ngInjectableDef;
10593
- },
10594
- });
10595
- }
10596
- // if NG_FACTORY_DEF is already defined on this class then don't overwrite it
10597
- if (!type.hasOwnProperty(NG_FACTORY_DEF)) {
10598
- Object.defineProperty(type, NG_FACTORY_DEF, {
10599
- get: () => {
10600
- if (ngFactoryDef === null) {
10601
- const compiler = getCompilerFacade({ usage: 0 /* JitCompilerUsage.Decorator */, kind: 'injectable', type });
10602
- ngFactoryDef = compiler.compileFactory(angularCoreDiEnv, `ng:///${type.name}/ɵfac.js`, {
10603
- name: type.name,
10604
- type,
10605
- typeArgumentCount: 0,
10606
- deps: reflectDependencies(type),
10607
- target: compiler.FactoryTarget.Injectable
10608
- });
10609
- }
10610
- return ngFactoryDef;
10611
- },
10612
- // Leave this configurable so that the factories from directives or pipes can take precedence.
10613
- configurable: true
10614
- });
10615
- }
10616
- }
10617
- const USE_VALUE = getClosureSafeProperty({ provide: String, useValue: getClosureSafeProperty });
10618
- function isUseClassProvider(meta) {
10619
- return meta.useClass !== undefined;
10620
- }
10621
- function isUseValueProvider(meta) {
10622
- return USE_VALUE in meta;
10623
- }
10624
- function isUseFactoryProvider(meta) {
10625
- return meta.useFactory !== undefined;
10626
- }
10627
- function isUseExistingProvider(meta) {
10628
- return meta.useExisting !== undefined;
10629
- }
10630
- function getInjectableMetadata(type, srcMeta) {
10631
- // Allow the compilation of a class with a `@Injectable()` decorator without parameters
10632
- const meta = srcMeta || { providedIn: null };
10633
- const compilerMeta = {
10634
- name: type.name,
10635
- type: type,
10636
- typeArgumentCount: 0,
10637
- providedIn: meta.providedIn,
10638
- };
10639
- if ((isUseClassProvider(meta) || isUseFactoryProvider(meta)) && meta.deps !== undefined) {
10640
- compilerMeta.deps = convertDependencies(meta.deps);
10641
- }
10642
- // Check to see if the user explicitly provided a `useXxxx` property.
10643
- if (isUseClassProvider(meta)) {
10644
- compilerMeta.useClass = meta.useClass;
10645
- }
10646
- else if (isUseValueProvider(meta)) {
10647
- compilerMeta.useValue = meta.useValue;
10648
- }
10649
- else if (isUseFactoryProvider(meta)) {
10650
- compilerMeta.useFactory = meta.useFactory;
10651
- }
10652
- else if (isUseExistingProvider(meta)) {
10653
- compilerMeta.useExisting = meta.useExisting;
10654
- }
10655
- return compilerMeta;
10656
- }
10657
-
10658
- /**
10659
- * Injectable decorator and metadata.
10660
- *
10661
- * @Annotation
10662
- * @publicApi
10663
- */
10664
- const Injectable = makeDecorator('Injectable', undefined, undefined, undefined, (type, meta) => compileInjectable(type, meta));
10665
-
10666
- /**
10667
- * Create a new `Injector` which is configured using a `defType` of `InjectorType<any>`s.
10668
- *
10669
- * @publicApi
10670
- */
10671
- function createInjector(defType, parent = null, additionalProviders = null, name) {
10672
- const injector = createInjectorWithoutInjectorInstances(defType, parent, additionalProviders, name);
10673
- injector.resolveInjectorInitializers();
10674
- return injector;
10675
- }
10676
- /**
10677
- * Creates a new injector without eagerly resolving its injector types. Can be used in places
10678
- * where resolving the injector types immediately can lead to an infinite loop. The injector types
10679
- * should be resolved at a later point by calling `_resolveInjectorDefTypes`.
10680
- */
10681
- function createInjectorWithoutInjectorInstances(defType, parent = null, additionalProviders = null, name, scopes = new Set()) {
10682
- const providers = [
10683
- additionalProviders || EMPTY_ARRAY,
10684
- importProvidersFrom(defType),
10685
- ];
10686
- name = name || (typeof defType === 'object' ? undefined : stringify(defType));
10687
- return new R3Injector(providers, parent || getNullInjector(), name || null, scopes);
10688
- }
10689
-
10690
- /**
10691
- * Concrete injectors implement this interface. Injectors are configured
10692
- * with [providers](guide/glossary#provider) that associate
10693
- * dependencies of various types with [injection tokens](guide/glossary#di-token).
10694
- *
10695
- * @see ["DI Providers"](guide/dependency-injection-providers).
10696
- * @see {@link StaticProvider}
10697
- *
10698
- * @usageNotes
10699
- *
10700
- * The following example creates a service injector instance.
10701
- *
10702
- * {@example core/di/ts/provider_spec.ts region='ConstructorProvider'}
10703
- *
10704
- * ### Usage example
10705
- *
10706
- * {@example core/di/ts/injector_spec.ts region='Injector'}
10707
- *
10708
- * `Injector` returns itself when given `Injector` as a token:
10709
- *
10710
- * {@example core/di/ts/injector_spec.ts region='injectInjector'}
10711
- *
10712
- * @publicApi
10713
- */
10714
- class Injector {
10715
- static { this.THROW_IF_NOT_FOUND = THROW_IF_NOT_FOUND; }
10716
- static { this.NULL = ( /* @__PURE__ */new NullInjector()); }
10717
- static create(options, parent) {
10718
- if (Array.isArray(options)) {
10719
- return createInjector({ name: '' }, parent, options, '');
10720
- }
10721
- else {
10722
- const name = options.name ?? '';
10723
- return createInjector({ name }, options.parent, options.providers, name);
10724
- }
10725
- }
10726
- /** @nocollapse */
10727
- static { this.ɵprov = ɵɵdefineInjectable({
10728
- token: Injector,
10729
- providedIn: 'any',
10730
- factory: () => ɵɵinject(INJECTOR),
10731
- }); }
10732
- /**
10733
- * @internal
10734
- * @nocollapse
10735
- */
10736
- static { this.__NG_ELEMENT_ID__ = -1 /* InjectorMarkers.Injector */; }
10737
- }
10738
-
10739
- /**
10740
- * @module
10741
- * @description
10742
- * The `di` module provides dependency injection container services.
10743
- */
10744
-
10745
- /**
10746
- * This file should not be necessary because node resolution should just default to `./di/index`!
10747
- *
10748
- * However it does not seem to work and it breaks:
10749
- * - //packages/animations/browser/test:test_web_chromium-local
10750
- * - //packages/compiler-cli/test:extract_i18n
10751
- * - //packages/compiler-cli/test:ngc
10752
- * - //packages/compiler-cli/test:perform_watch
10753
- * - //packages/compiler-cli/test/diagnostics:check_types
10754
- * - //packages/compiler-cli/test/transformers:test
10755
- * - //packages/compiler/test:test
10756
- * - //tools/public_api_guard:core_api
10757
- *
10758
- * Remove this file once the above is solved or wait until `ngc` is deleted and then it should be
10759
- * safe to delete this file.
10760
- */
11161
+ // will be altered by the time we leave the `ɵɵadvance` instruction.
11162
+ setSelectedIndex(index);
11163
+ }
10761
11164
 
10762
11165
  function ɵɵdirectiveInject(token, flags = InjectFlags.Default) {
10763
11166
  const lView = getLView();
@@ -10769,7 +11172,9 @@ function ɵɵdirectiveInject(token, flags = InjectFlags.Default) {
10769
11172
  return ɵɵinject(token, flags);
10770
11173
  }
10771
11174
  const tNode = getCurrentTNode();
10772
- return getOrCreateInjectable(tNode, lView, resolveForwardRef(token), flags);
11175
+ const value = getOrCreateInjectable(tNode, lView, resolveForwardRef(token), flags);
11176
+ ngDevMode && emitInjectEvent(token, value, flags);
11177
+ return value;
10773
11178
  }
10774
11179
  /**
10775
11180
  * Throws an error indicating that a factory function could not be generated by the compiler for a
@@ -12210,40 +12615,6 @@ function renderChildComponents(hostLView, components) {
12210
12615
  }
12211
12616
  }
12212
12617
 
12213
- /**
12214
- * `DestroyRef` lets you set callbacks to run for any cleanup or destruction behavior.
12215
- * The scope of this destruction depends on where `DestroyRef` is injected. If `DestroyRef`
12216
- * is injected in a component or directive, the callbacks run when that component or
12217
- * directive is destroyed. Otherwise the callbacks run when a corresponding injector is destroyed.
12218
- *
12219
- * @publicApi
12220
- */
12221
- class DestroyRef {
12222
- /**
12223
- * @internal
12224
- * @nocollapse
12225
- */
12226
- static { this.__NG_ELEMENT_ID__ = injectDestroyRef; }
12227
- /**
12228
- * @internal
12229
- * @nocollapse
12230
- */
12231
- static { this.__NG_ENV_ID__ = (injector) => injector; }
12232
- }
12233
- class NodeInjectorDestroyRef extends DestroyRef {
12234
- constructor(_lView) {
12235
- super();
12236
- this._lView = _lView;
12237
- }
12238
- onDestroy(callback) {
12239
- storeLViewOnDestroy(this._lView, callback);
12240
- return () => removeLViewOnDestroy(this._lView, callback);
12241
- }
12242
- }
12243
- function injectDestroyRef() {
12244
- return new NodeInjectorDestroyRef(getLView());
12245
- }
12246
-
12247
12618
  /**
12248
12619
  * Tracks all effects registered within a given application and runs them via `flush`.
12249
12620
  */
@@ -12412,13 +12783,17 @@ function collectNativeNodes(tView, lView, tNode, result, isProjection = false) {
12412
12783
  }
12413
12784
 
12414
12785
  function detectChangesInternal(tView, lView, context, notifyErrorHandler = true) {
12415
- const rendererFactory = lView[ENVIRONMENT].rendererFactory;
12786
+ const environment = lView[ENVIRONMENT];
12787
+ const rendererFactory = environment.rendererFactory;
12788
+ const afterRenderEventManager = environment.afterRenderEventManager;
12416
12789
  // Check no changes mode is a dev only mode used to verify that bindings have not changed
12417
12790
  // since they were assigned. We do not want to invoke renderer factory functions in that mode
12418
12791
  // to avoid any possible side-effects.
12419
12792
  const checkNoChangesMode = !!ngDevMode && isInCheckNoChangesMode();
12420
- if (!checkNoChangesMode && rendererFactory.begin)
12421
- rendererFactory.begin();
12793
+ if (!checkNoChangesMode) {
12794
+ rendererFactory.begin?.();
12795
+ afterRenderEventManager?.begin();
12796
+ }
12422
12797
  try {
12423
12798
  refreshView(tView, lView, tView.template, context);
12424
12799
  }
@@ -12429,11 +12804,14 @@ function detectChangesInternal(tView, lView, context, notifyErrorHandler = true)
12429
12804
  throw error;
12430
12805
  }
12431
12806
  finally {
12432
- if (!checkNoChangesMode && rendererFactory.end)
12433
- rendererFactory.end();
12434
- // One final flush of the effects queue to catch any effects created in `ngAfterViewInit` or
12435
- // other post-order hooks.
12436
- !checkNoChangesMode && lView[ENVIRONMENT].effectManager?.flush();
12807
+ if (!checkNoChangesMode) {
12808
+ rendererFactory.end?.();
12809
+ // One final flush of the effects queue to catch any effects created in `ngAfterViewInit` or
12810
+ // other post-order hooks.
12811
+ environment.effectManager?.flush();
12812
+ // Invoke all callbacks registered via `after*Render`, if needed.
12813
+ afterRenderEventManager?.end();
12814
+ }
12437
12815
  }
12438
12816
  }
12439
12817
  function checkNoChangesInternal(tView, lView, context, notifyErrorHandler = true) {
@@ -13054,10 +13432,12 @@ class ComponentFactory extends ComponentFactory$1 {
13054
13432
  }
13055
13433
  const sanitizer = rootViewInjector.get(Sanitizer, null);
13056
13434
  const effectManager = rootViewInjector.get(EffectManager, null);
13435
+ const afterRenderEventManager = rootViewInjector.get(AfterRenderEventManager, null);
13057
13436
  const environment = {
13058
13437
  rendererFactory,
13059
13438
  sanitizer,
13060
13439
  effectManager,
13440
+ afterRenderEventManager,
13061
13441
  };
13062
13442
  const hostRenderer = rendererFactory.createRenderer(null, this.componentDef);
13063
13443
  // Determine a tag name used for creating host elements when this component is created
@@ -13175,12 +13555,6 @@ class ComponentRef extends ComponentRef$1 {
13175
13555
  this.hostView.onDestroy(callback);
13176
13556
  }
13177
13557
  }
13178
- // TODO: A hack to not pull in the NullInjector from @angular/core.
13179
- const NULL_INJECTOR = {
13180
- get: (token, notFoundValue) => {
13181
- throwProviderNotFoundError(token, 'NullInjector');
13182
- }
13183
- };
13184
13558
  /** Creates a TNode that can be used to instantiate a root component. */
13185
13559
  function createRootComponentTNode(lView, rNode) {
13186
13560
  const tView = lView[TVIEW];
@@ -21290,6 +21664,18 @@ function ɵɵi18nPostprocess(message, replacements = {}) {
21290
21664
  return i18nPostprocess(message, replacements);
21291
21665
  }
21292
21666
 
21667
+ /**
21668
+ * Creates runtime data structures for `{#defer}` blocks.
21669
+ *
21670
+ * @param index The index of the defer block in the data array
21671
+ * @param deferredDepsFn Function that contains dependencies for this defer block
21672
+ *
21673
+ * @codeGenApi
21674
+ */
21675
+ function ɵɵdefer(index, deferredDepsFn) {
21676
+ // TODO: implement runtime logic.
21677
+ }
21678
+
21293
21679
  /*
21294
21680
  * This file re-exports all symbols contained in this directory.
21295
21681
  *
@@ -21354,9 +21740,15 @@ function resolveProvider(provider, tInjectables, lInjectablesBlueprint, isCompon
21354
21740
  else {
21355
21741
  const tView = getTView();
21356
21742
  const lView = getLView();
21357
- let token = isTypeProvider(provider) ? provider : resolveForwardRef(provider.provide);
21358
- let providerFactory = providerToFactory(provider);
21359
21743
  const tNode = getCurrentTNode();
21744
+ let token = isTypeProvider(provider) ? provider : resolveForwardRef(provider.provide);
21745
+ const providerFactory = providerToFactory(provider);
21746
+ if (ngDevMode) {
21747
+ const injector = new NodeInjector(tNode, lView);
21748
+ runInInjectorProfilerContext(injector, token, () => {
21749
+ emitProviderConfiguredEvent(provider, isViewProvider);
21750
+ });
21751
+ }
21360
21752
  const beginIndex = tNode.providerIndexes & 1048575 /* TNodeProviderIndexes.ProvidersStartIndexMask */;
21361
21753
  const endIndex = tNode.directiveStart;
21362
21754
  const cptViewProvidersCount = tNode.providerIndexes >> 20 /* TNodeProviderIndexes.CptViewProvidersCountShift */;
@@ -22576,6 +22968,13 @@ function ɵɵpipe(index, pipeName) {
22576
22968
  pipeDef = tView.data[adjustedIndex];
22577
22969
  }
22578
22970
  const pipeFactory = pipeDef.factory || (pipeDef.factory = getFactoryDef(pipeDef.type, true));
22971
+ let previousInjectorProfilerContext;
22972
+ if (ngDevMode) {
22973
+ previousInjectorProfilerContext = setInjectorProfilerContext({
22974
+ injector: new NodeInjector(getCurrentTNode(), getLView()),
22975
+ token: pipeDef.type
22976
+ });
22977
+ }
22579
22978
  const previousInjectImplementation = setInjectImplementation(ɵɵdirectiveInject);
22580
22979
  try {
22581
22980
  // DI for pipes is supposed to behave like directives when placed on a component
@@ -22590,6 +22989,7 @@ function ɵɵpipe(index, pipeName) {
22590
22989
  // we have to restore the injector implementation in finally, just in case the creation of the
22591
22990
  // pipe throws an error.
22592
22991
  setInjectImplementation(previousInjectImplementation);
22992
+ ngDevMode && setInjectorProfilerContext(previousInjectorProfilerContext);
22593
22993
  }
22594
22994
  }
22595
22995
  /**
@@ -23305,7 +23705,7 @@ const R3ViewContainerRef = class ViewContainerRef extends VE_ViewContainerRef {
23305
23705
  let index;
23306
23706
  // This function supports 2 signatures and we need to handle options correctly for both:
23307
23707
  // 1. When first argument is a Component type. This signature also requires extra
23308
- // options to be provided as as object (more ergonomic option).
23708
+ // options to be provided as object (more ergonomic option).
23309
23709
  // 2. First argument is a Component factory. In this case extra options are represented as
23310
23710
  // positional arguments. This signature is less ergonomic and will be deprecated.
23311
23711
  if (isComponentFactory) {
@@ -24169,6 +24569,7 @@ const angularCoreEnv = (() => ({
24169
24569
  'ɵɵclassProp': ɵɵclassProp,
24170
24570
  'ɵɵadvance': ɵɵadvance,
24171
24571
  'ɵɵtemplate': ɵɵtemplate,
24572
+ 'ɵɵdefer': ɵɵdefer,
24172
24573
  'ɵɵtext': ɵɵtext,
24173
24574
  'ɵɵtextInterpolate': ɵɵtextInterpolate,
24174
24575
  'ɵɵtextInterpolate1': ɵɵtextInterpolate1,
@@ -25867,6 +26268,206 @@ const COMPILER_OPTIONS = new InjectionToken('compilerOptions');
25867
26268
  class CompilerFactory {
25868
26269
  }
25869
26270
 
26271
+ /**
26272
+ * These are the data structures that our framework injector profiler will fill with data in order
26273
+ * to support DI debugging APIs.
26274
+ *
26275
+ * resolverToTokenToDependencies: Maps an injector to a Map of tokens to an Array of
26276
+ * dependencies. Injector -> Token -> Dependencies This is used to support the
26277
+ * getDependenciesFromInjectable API, which takes in an injector and a token and returns it's
26278
+ * dependencies.
26279
+ *
26280
+ * resolverToProviders: Maps a DI resolver (an Injector or an LView) to the providers configured
26281
+ * within it This is used to support the getInjectorProviders API, which takes in an injector and
26282
+ * returns the providers that it was configured with.
26283
+ *
26284
+ * standaloneInjectorToComponent: Maps the injector of a standalone component to the standalone
26285
+ * component that it is associated with. Used in the getInjectorProviders API, specificially in the
26286
+ * discovery of import paths for each provider. This is necessary because the imports array of a
26287
+ * standalone component is processed and configured in its standalone injector, but exists within
26288
+ * the component's definition. Because getInjectorProviders takes in an injector, if that injector
26289
+ * is the injector of a standalone component, we need to be able to discover the place where the
26290
+ * imports array is located (the component) in order to flatten the imports array within it to
26291
+ * discover all of it's providers.
26292
+ *
26293
+ *
26294
+ * All of these data structures are instantiated with WeakMaps. This will ensure that the presence
26295
+ * of any object in the keys of these maps does not prevent the garbage collector from collecting
26296
+ * those objects. Because of this property of WeakMaps, these data structures will never be the
26297
+ * source of a memory leak.
26298
+ *
26299
+ * An example of this advantage: When components are destroyed, we don't need to do
26300
+ * any additional work to remove that component from our mappings.
26301
+ *
26302
+ */
26303
+ class DIDebugData {
26304
+ constructor() {
26305
+ this.resolverToTokenToDependencies = new WeakMap();
26306
+ this.resolverToProviders = new WeakMap();
26307
+ this.standaloneInjectorToComponent = new WeakMap();
26308
+ }
26309
+ reset() {
26310
+ this.resolverToTokenToDependencies =
26311
+ new WeakMap();
26312
+ this.resolverToProviders = new WeakMap();
26313
+ this.standaloneInjectorToComponent = new WeakMap();
26314
+ }
26315
+ }
26316
+ let frameworkDIDebugData = new DIDebugData();
26317
+ function getFrameworkDIDebugData() {
26318
+ return frameworkDIDebugData;
26319
+ }
26320
+ /**
26321
+ * Initalize default handling of injector events. This handling parses events
26322
+ * as they are emitted and constructs the data structures necessary to support
26323
+ * some of debug APIs.
26324
+ *
26325
+ * See handleInjectEvent, handleCreateEvent and handleProviderConfiguredEvent
26326
+ * for descriptions of each handler
26327
+ *
26328
+ * Supported APIs:
26329
+ * - getDependenciesFromInjectable
26330
+ * - getInjectorProviders
26331
+ */
26332
+ function setupFrameworkInjectorProfiler() {
26333
+ frameworkDIDebugData.reset();
26334
+ setInjectorProfiler((injectorProfilerEvent) => handleInjectorProfilerEvent(injectorProfilerEvent));
26335
+ }
26336
+ function handleInjectorProfilerEvent(injectorProfilerEvent) {
26337
+ const { context, type } = injectorProfilerEvent;
26338
+ if (type === 0 /* InjectorProfilerEventType.Inject */) {
26339
+ handleInjectEvent(context, injectorProfilerEvent.service);
26340
+ }
26341
+ else if (type === 1 /* InjectorProfilerEventType.InstanceCreatedByInjector */) {
26342
+ handleInstanceCreatedByInjectorEvent(context, injectorProfilerEvent.instance);
26343
+ }
26344
+ else if (type === 2 /* InjectorProfilerEventType.ProviderConfigured */) {
26345
+ handleProviderConfiguredEvent(context, injectorProfilerEvent.providerRecord);
26346
+ }
26347
+ }
26348
+ /**
26349
+ *
26350
+ * Stores the injected service in frameworkDIDebugData.resolverToTokenToDependencies
26351
+ * based on it's injector and token.
26352
+ *
26353
+ * @param context InjectorProfilerContext the injection context that this event occurred in.
26354
+ * @param data InjectedService the service associated with this inject event.
26355
+ *
26356
+ */
26357
+ function handleInjectEvent(context, data) {
26358
+ const diResolver = getDIResolver(context.injector);
26359
+ if (diResolver === null) {
26360
+ throwError('An Inject event must be run within an injection context.');
26361
+ }
26362
+ const diResolverToInstantiatedToken = frameworkDIDebugData.resolverToTokenToDependencies;
26363
+ if (!diResolverToInstantiatedToken.has(diResolver)) {
26364
+ diResolverToInstantiatedToken.set(diResolver, new WeakMap());
26365
+ }
26366
+ // if token is a primitive type, ignore this event. We do this because we cannot keep track of
26367
+ // non-primitive tokens in WeakMaps since they are not garbage collectable.
26368
+ if (!canBeHeldWeakly(context.token)) {
26369
+ return;
26370
+ }
26371
+ const instantiatedTokenToDependencies = diResolverToInstantiatedToken.get(diResolver);
26372
+ if (!instantiatedTokenToDependencies.has(context.token)) {
26373
+ instantiatedTokenToDependencies.set(context.token, []);
26374
+ }
26375
+ const { token, value, flags } = data;
26376
+ instantiatedTokenToDependencies.get(context.token).push({ token, value, flags });
26377
+ }
26378
+ /**
26379
+ *
26380
+ * If the created instance is an instance of a standalone component, maps the injector to that
26381
+ * standalone component in frameworkDIDebugData.standaloneInjectorToComponent
26382
+ *
26383
+ * @param context InjectorProfilerContext the injection context that this event occurred in.
26384
+ * @param data InjectorCreatedInstance an object containing the instance that was just created
26385
+ *
26386
+ */
26387
+ function handleInstanceCreatedByInjectorEvent(context, data) {
26388
+ const { value } = data;
26389
+ if (getDIResolver(context.injector) === null) {
26390
+ throwError('An InjectorCreatedInstance event must be run within an injection context.');
26391
+ }
26392
+ // if our value is an instance of a standalone component, map the injector of that standalone
26393
+ // component to the component class. Otherwise, this event is a noop.
26394
+ let standaloneComponent = undefined;
26395
+ if (typeof value === 'object') {
26396
+ standaloneComponent = value?.constructor;
26397
+ }
26398
+ if (standaloneComponent === undefined || !isStandaloneComponent(standaloneComponent)) {
26399
+ return;
26400
+ }
26401
+ const environmentInjector = context.injector.get(EnvironmentInjector, null, { optional: true });
26402
+ // Standalone components should have an environment injector. If one cannot be
26403
+ // found we may be in a test case for low level functionality that did not explictly
26404
+ // setup this injector. In those cases, we simply ignore this event.
26405
+ if (environmentInjector === null) {
26406
+ return;
26407
+ }
26408
+ const { standaloneInjectorToComponent } = frameworkDIDebugData;
26409
+ // If our injector has already been mapped, as is the case
26410
+ // when a standalone component imports another standalone component,
26411
+ // we consider the original component (the component doing the importing)
26412
+ // as the component connected to our injector.
26413
+ if (standaloneInjectorToComponent.has(environmentInjector)) {
26414
+ return;
26415
+ }
26416
+ // If our injector hasn't been mapped, then we map it to the standalone component
26417
+ standaloneInjectorToComponent.set(environmentInjector, standaloneComponent);
26418
+ }
26419
+ function isStandaloneComponent(value) {
26420
+ const def = getComponentDef(value);
26421
+ return !!def?.standalone;
26422
+ }
26423
+ /**
26424
+ *
26425
+ * Stores the emitted ProviderRecords from the InjectorProfilerEventType.ProviderConfigured
26426
+ * event in frameworkDIDebugData.resolverToProviders
26427
+ *
26428
+ * @param context InjectorProfilerContext the injection context that this event occurred in.
26429
+ * @param data ProviderRecord an object containing the instance that was just created
26430
+ *
26431
+ */
26432
+ function handleProviderConfiguredEvent(context, data) {
26433
+ const { resolverToProviders } = frameworkDIDebugData;
26434
+ const diResolver = getDIResolver(context?.injector);
26435
+ if (diResolver === null) {
26436
+ throwError('A ProviderConfigured event must be run within an injection context.');
26437
+ }
26438
+ if (!resolverToProviders.has(diResolver)) {
26439
+ resolverToProviders.set(diResolver, []);
26440
+ }
26441
+ resolverToProviders.get(diResolver).push(data);
26442
+ }
26443
+ function getDIResolver(injector) {
26444
+ let diResolver = null;
26445
+ if (injector === undefined) {
26446
+ return diResolver;
26447
+ }
26448
+ // We use the LView as the diResolver for NodeInjectors because they
26449
+ // do not persist anywhere in the framework. They are simply wrappers around an LView and a TNode
26450
+ // that do persist. Because of this, we rely on the LView of the NodeInjector in order to use
26451
+ // as a concrete key to represent this injector. If we get the same LView back later, we know
26452
+ // we're looking at the same injector.
26453
+ if (injector instanceof NodeInjector) {
26454
+ diResolver = getNodeInjectorLView(injector);
26455
+ }
26456
+ // Other injectors can be used a keys for a map because their instances
26457
+ // persist
26458
+ else {
26459
+ diResolver = injector;
26460
+ }
26461
+ return diResolver;
26462
+ }
26463
+ // inspired by
26464
+ // https://tc39.es/ecma262/multipage/executable-code-and-execution-contexts.html#sec-canbeheldweakly
26465
+ function canBeHeldWeakly(value) {
26466
+ // we check for value !== null here because typeof null === 'object
26467
+ return value !== null &&
26468
+ (typeof value === 'object' || typeof value === 'function' || typeof value === 'symbol');
26469
+ }
26470
+
25870
26471
  /**
25871
26472
  * Marks a component for check (in case of OnPush components) and synchronously
25872
26473
  * performs change detection on the application this component belongs to.
@@ -25882,6 +26483,447 @@ function applyChanges(component) {
25882
26483
  getRootComponents(component).forEach(rootComponent => detectChanges(rootComponent));
25883
26484
  }
25884
26485
 
26486
+ /**
26487
+ * Discovers the dependencies of an injectable instance. Provides DI information about each
26488
+ * dependency that the injectable was instantiated with, including where they were provided from.
26489
+ *
26490
+ * @param injector An injector instance
26491
+ * @param token a DI token that was constructed by the given injector instance
26492
+ * @returns an object that contains the created instance of token as well as all of the dependencies
26493
+ * that it was instantiated with OR undefined if the token was not created within the given
26494
+ * injector.
26495
+ */
26496
+ function getDependenciesFromInjectable(injector, token) {
26497
+ // First we check to see if the token given maps to an actual instance in the injector given.
26498
+ // We use `self: true` because we only want to look at the injector we were given.
26499
+ // We use `optional: true` because it's possible that the token we were given was never
26500
+ // constructed by the injector we were given.
26501
+ const instance = injector.get(token, null, { self: true, optional: true });
26502
+ if (instance === null) {
26503
+ throw new Error(`Unable to determine instance of ${token} in given injector`);
26504
+ }
26505
+ let diResolver = injector;
26506
+ if (injector instanceof NodeInjector) {
26507
+ diResolver = getNodeInjectorLView(injector);
26508
+ }
26509
+ const { resolverToTokenToDependencies } = getFrameworkDIDebugData();
26510
+ let dependencies = resolverToTokenToDependencies.get(diResolver)?.get?.(token) ?? [];
26511
+ const resolutionPath = getInjectorResolutionPath(injector);
26512
+ dependencies = dependencies.map(dep => {
26513
+ const flags = dep.flags;
26514
+ dep.flags = {
26515
+ optional: (8 /* InternalInjectFlags.Optional */ & flags) === 8 /* InternalInjectFlags.Optional */,
26516
+ host: (1 /* InternalInjectFlags.Host */ & flags) === 1 /* InternalInjectFlags.Host */,
26517
+ self: (2 /* InternalInjectFlags.Self */ & flags) === 2 /* InternalInjectFlags.Self */,
26518
+ skipSelf: (4 /* InternalInjectFlags.SkipSelf */ & flags) === 4 /* InternalInjectFlags.SkipSelf */,
26519
+ };
26520
+ for (let i = 0; i < resolutionPath.length; i++) {
26521
+ const injectorToCheck = resolutionPath[i];
26522
+ // if skipSelf is true we skip the first injector
26523
+ if (i === 0 && dep.flags.skipSelf) {
26524
+ continue;
26525
+ }
26526
+ // host only applies to NodeInjectors
26527
+ if (dep.flags.host && injectorToCheck instanceof EnvironmentInjector) {
26528
+ break;
26529
+ }
26530
+ const instance = injectorToCheck.get(dep.token, null, { self: true, optional: true });
26531
+ if (instance !== null) {
26532
+ // if host flag is true we double check that we can get the service from the first element
26533
+ // in the resolution path by using the host flag. This is done to make sure that we've found
26534
+ // the correct providing injector, and not a node injector that is connected to our path via
26535
+ // a router outlet.
26536
+ if (dep.flags.host) {
26537
+ const firstInjector = resolutionPath[0];
26538
+ const lookupFromFirstInjector = firstInjector.get(dep.token, null, { ...dep.flags, optional: true });
26539
+ if (lookupFromFirstInjector !== null) {
26540
+ dep.providedIn = injectorToCheck;
26541
+ }
26542
+ break;
26543
+ }
26544
+ dep.providedIn = injectorToCheck;
26545
+ break;
26546
+ }
26547
+ // if self is true we stop after the first injector
26548
+ if (i === 0 && dep.flags.self) {
26549
+ break;
26550
+ }
26551
+ }
26552
+ return dep;
26553
+ });
26554
+ return { instance, dependencies };
26555
+ }
26556
+ /**
26557
+ * Gets the class associated with an injector that contains a provider `imports` array in it's
26558
+ * definition
26559
+ *
26560
+ * For Module Injectors this returns the NgModule constructor.
26561
+ *
26562
+ * For Standalone injectors this returns the standalone component constructor.
26563
+ *
26564
+ * @param injector Injector an injector instance
26565
+ * @returns the constructor where the `imports` array that configures this injector is located
26566
+ */
26567
+ function getProviderImportsContainer(injector) {
26568
+ const { standaloneInjectorToComponent } = getFrameworkDIDebugData();
26569
+ // standalone components configure providers through a component def, so we have to
26570
+ // use the standalone component associated with this injector if Injector represents
26571
+ // a standalone components EnvironmentInjector
26572
+ if (standaloneInjectorToComponent.has(injector)) {
26573
+ return standaloneInjectorToComponent.get(injector);
26574
+ }
26575
+ // Module injectors configure providers through their NgModule def, so we use the
26576
+ // injector to lookup its NgModuleRef and through that grab its instance
26577
+ const defTypeRef = injector.get(NgModuleRef$1, null, { self: true, optional: true });
26578
+ // If we can't find an associated imports container, return null.
26579
+ // This could be the case if this function is called with an R3Injector that does not represent
26580
+ // a standalone component or NgModule.
26581
+ if (defTypeRef === null) {
26582
+ return null;
26583
+ }
26584
+ return defTypeRef.instance.constructor;
26585
+ }
26586
+ /**
26587
+ * Gets the providers configured on a NodeInjector
26588
+ *
26589
+ * @param injector A NodeInjector instance
26590
+ * @returns ProviderRecord[] an array of objects representing the providers configured on this
26591
+ * injector
26592
+ */
26593
+ function getNodeInjectorProviders(injector) {
26594
+ const diResolver = getNodeInjectorLView(injector);
26595
+ const { resolverToProviders } = getFrameworkDIDebugData();
26596
+ return resolverToProviders.get(diResolver) ?? [];
26597
+ }
26598
+ /**
26599
+ * Gets a mapping of providers configured on an injector to their import paths
26600
+ *
26601
+ * ModuleA -> imports ModuleB
26602
+ * ModuleB -> imports ModuleC
26603
+ * ModuleB -> provides MyServiceA
26604
+ * ModuleC -> provides MyServiceB
26605
+ *
26606
+ * getProviderImportPaths(ModuleA)
26607
+ * > Map(2) {
26608
+ * MyServiceA => [ModuleA, ModuleB]
26609
+ * MyServiceB => [ModuleA, ModuleB, ModuleC]
26610
+ * }
26611
+ *
26612
+ * @param providerImportsContainer constructor of class that contains an `imports` array in it's
26613
+ * definition
26614
+ * @returns A Map object that maps providers to an array of constructors representing it's import
26615
+ * path
26616
+ *
26617
+ */
26618
+ function getProviderImportPaths(providerImportsContainer) {
26619
+ const providerToPath = new Map();
26620
+ const visitedContainers = new Set();
26621
+ const visitor = walkProviderTreeToDiscoverImportPaths(providerToPath, visitedContainers);
26622
+ walkProviderTree(providerImportsContainer, visitor, [], new Set());
26623
+ return providerToPath;
26624
+ }
26625
+ /**
26626
+ *
26627
+ * Higher order function that returns a visitor for WalkProviderTree
26628
+ *
26629
+ * Takes in a Map and Set to keep track of the providers and containers
26630
+ * visited, so that we can discover the import paths of these providers
26631
+ * during the traversal.
26632
+ *
26633
+ * This visitor takes advantage of the fact that walkProviderTree performs a
26634
+ * postorder traversal of the provider tree for the passed in container. Because postorder
26635
+ * traversal recursively processes subtrees from leaf nodes until the traversal reaches the root,
26636
+ * we write a visitor that constructs provider import paths in reverse.
26637
+ *
26638
+ *
26639
+ * We use the visitedContainers set defined outside this visitor
26640
+ * because we want to run some logic only once for
26641
+ * each container in the tree. That logic can be described as:
26642
+ *
26643
+ *
26644
+ * 1. for each discovered_provider and discovered_path in the incomplete provider paths we've
26645
+ * already discovered
26646
+ * 2. get the first container in discovered_path
26647
+ * 3. if that first container is in the imports array of the container we're visiting
26648
+ * Then the container we're visiting is also in the import path of discovered_provider, so we
26649
+ * unshift discovered_path with the container we're currently visiting
26650
+ *
26651
+ *
26652
+ * Example Run:
26653
+ * ```
26654
+ * ┌──────────┐
26655
+ * │containerA│
26656
+ * ┌─imports-─┤ ├──imports─┐
26657
+ * │ │ provA │ │
26658
+ * │ │ provB │ │
26659
+ * │ └──────────┘ │
26660
+ * │ │
26661
+ * ┌▼─────────┐ ┌────────▼─┐
26662
+ * │containerB│ │containerC│
26663
+ * │ │ │ │
26664
+ * │ provD │ │ provF │
26665
+ * │ provE │ │ provG │
26666
+ * └──────────┘ └──────────┘
26667
+ * ```
26668
+ *
26669
+ * Each step of the traversal,
26670
+ *
26671
+ * ```
26672
+ * visitor(provD, containerB)
26673
+ * providerToPath === Map { provD => [containerB] }
26674
+ * visitedContainers === Set { containerB }
26675
+ *
26676
+ * visitor(provE, containerB)
26677
+ * providerToPath === Map { provD => [containerB], provE => [containerB] }
26678
+ * visitedContainers === Set { containerB }
26679
+ *
26680
+ * visitor(provF, containerC)
26681
+ * providerToPath === Map { provD => [containerB], provE => [containerB], provF => [containerC] }
26682
+ * visitedContainers === Set { containerB, containerC }
26683
+ *
26684
+ * visitor(provG, containerC)
26685
+ * providerToPath === Map {
26686
+ * provD => [containerB], provE => [containerB], provF => [containerC], provG => [containerC]
26687
+ * }
26688
+ * visitedContainers === Set { containerB, containerC }
26689
+ *
26690
+ * visitor(provA, containerA)
26691
+ * providerToPath === Map {
26692
+ * provD => [containerA, containerB],
26693
+ * provE => [containerA, containerB],
26694
+ * provF => [containerA, containerC],
26695
+ * provG => [containerA, containerC],
26696
+ * provA => [containerA]
26697
+ * }
26698
+ * visitedContainers === Set { containerB, containerC, containerA }
26699
+ *
26700
+ * visitor(provB, containerA)
26701
+ * providerToPath === Map {
26702
+ * provD => [containerA, containerB],
26703
+ * provE => [containerA, containerB],
26704
+ * provF => [containerA, containerC],
26705
+ * provG => [containerA, containerC],
26706
+ * provA => [containerA]
26707
+ * provB => [containerA]
26708
+ * }
26709
+ * visitedContainers === Set { containerB, containerC, containerA }
26710
+ * ```
26711
+ *
26712
+ * @param providerToPath Map map of providers to paths that this function fills
26713
+ * @param visitedContainers Set a set to keep track of the containers we've already visited
26714
+ * @return function(provider SingleProvider, container: Type<unknown> | InjectorType<unknown>) =>
26715
+ * void
26716
+ */
26717
+ function walkProviderTreeToDiscoverImportPaths(providerToPath, visitedContainers) {
26718
+ return (provider, container) => {
26719
+ // If the provider is not already in the providerToPath map,
26720
+ // add an entry with the provider as the key and an array containing the current container as
26721
+ // the value
26722
+ if (!providerToPath.has(provider)) {
26723
+ providerToPath.set(provider, [container]);
26724
+ }
26725
+ // This block will run exactly once for each container in the import tree.
26726
+ // This is where we run the logic to check the imports array of the current
26727
+ // container to see if it's the next container in the path for our currently
26728
+ // discovered providers.
26729
+ if (!visitedContainers.has(container)) {
26730
+ // Iterate through the providers we've already seen
26731
+ for (const prov of providerToPath.keys()) {
26732
+ const existingImportPath = providerToPath.get(prov);
26733
+ let containerDef = getInjectorDef(container);
26734
+ if (!containerDef) {
26735
+ const ngModule = container.ngModule;
26736
+ containerDef = getInjectorDef(ngModule);
26737
+ }
26738
+ if (!containerDef) {
26739
+ return;
26740
+ }
26741
+ const lastContainerAddedToPath = existingImportPath[0];
26742
+ let isNextStepInPath = false;
26743
+ deepForEach(containerDef.imports, (moduleImport) => {
26744
+ if (isNextStepInPath) {
26745
+ return;
26746
+ }
26747
+ isNextStepInPath = moduleImport.ngModule === lastContainerAddedToPath ||
26748
+ moduleImport === lastContainerAddedToPath;
26749
+ if (isNextStepInPath) {
26750
+ providerToPath.get(prov)?.unshift(container);
26751
+ }
26752
+ });
26753
+ }
26754
+ }
26755
+ visitedContainers.add(container);
26756
+ };
26757
+ }
26758
+ /**
26759
+ * Gets the providers configured on an EnvironmentInjector
26760
+ *
26761
+ * @param injector EnvironmentInjector
26762
+ * @returns an array of objects representing the providers of the given injector
26763
+ */
26764
+ function getEnvironmentInjectorProviders(injector) {
26765
+ const providerImportsContainer = getProviderImportsContainer(injector);
26766
+ if (providerImportsContainer === null) {
26767
+ throwError('Could not determine where injector providers were configured.');
26768
+ }
26769
+ const providerToPath = getProviderImportPaths(providerImportsContainer);
26770
+ const providerRecords = getFrameworkDIDebugData().resolverToProviders.get(injector) ?? [];
26771
+ return providerRecords.map(providerRecord => {
26772
+ let importPath = providerToPath.get(providerRecord.provider) ?? [providerImportsContainer];
26773
+ const def = getComponentDef(providerImportsContainer);
26774
+ const isStandaloneComponent = !!def?.standalone;
26775
+ // We prepend the component constructor in the standalone case
26776
+ // because walkProviderTree does not visit this constructor during it's traversal
26777
+ if (isStandaloneComponent) {
26778
+ importPath = [providerImportsContainer, ...providerToPath.get(providerRecord.provider) ?? []];
26779
+ }
26780
+ return { ...providerRecord, importPath };
26781
+ });
26782
+ }
26783
+ /**
26784
+ * Gets the providers configured on an injector.
26785
+ *
26786
+ * @param injector the injector to lookup the providers of
26787
+ * @returns ProviderRecord[] an array of objects representing the providers of the given injector
26788
+ */
26789
+ function getInjectorProviders(injector) {
26790
+ if (injector instanceof NodeInjector) {
26791
+ return getNodeInjectorProviders(injector);
26792
+ }
26793
+ else if (injector instanceof EnvironmentInjector) {
26794
+ return getEnvironmentInjectorProviders(injector);
26795
+ }
26796
+ throwError('getInjectorProviders only supports NodeInjector and EnvironmentInjector');
26797
+ }
26798
+ function getInjectorResolutionPath(injector) {
26799
+ const resolutionPath = [injector];
26800
+ getInjectorResolutionPathHelper(injector, resolutionPath);
26801
+ return resolutionPath;
26802
+ }
26803
+ function getInjectorResolutionPathHelper(injector, resolutionPath) {
26804
+ const parent = getInjectorParent(injector);
26805
+ // if getInjectorParent can't find a parent, then we've either reached the end
26806
+ // of the path, or we need to move from the Element Injector tree to the
26807
+ // module injector tree using the first injector in our path as the connection point.
26808
+ if (parent === null) {
26809
+ if (injector instanceof NodeInjector) {
26810
+ const firstInjector = resolutionPath[0];
26811
+ if (firstInjector instanceof NodeInjector) {
26812
+ const moduleInjector = getModuleInjectorOfNodeInjector(firstInjector);
26813
+ if (moduleInjector === null) {
26814
+ throwError('NodeInjector must have some connection to the module injector tree');
26815
+ }
26816
+ resolutionPath.push(moduleInjector);
26817
+ getInjectorResolutionPathHelper(moduleInjector, resolutionPath);
26818
+ }
26819
+ return resolutionPath;
26820
+ }
26821
+ }
26822
+ else {
26823
+ resolutionPath.push(parent);
26824
+ getInjectorResolutionPathHelper(parent, resolutionPath);
26825
+ }
26826
+ return resolutionPath;
26827
+ }
26828
+ /**
26829
+ * Gets the parent of an injector.
26830
+ *
26831
+ * This function is not able to make the jump from the Element Injector Tree to the Module
26832
+ * injector tree. This is because the "parent" (the next step in the reoslution path)
26833
+ * of a root NodeInjector is dependent on which NodeInjector ancestor initiated
26834
+ * the DI lookup. See getInjectorResolutionPath for a function that can make this jump.
26835
+ *
26836
+ * In the below diagram:
26837
+ * ```ts
26838
+ * getInjectorParent(NodeInjectorB)
26839
+ * > NodeInjectorA
26840
+ * getInjectorParent(NodeInjectorA) // or getInjectorParent(getInjectorParent(NodeInjectorB))
26841
+ * > null // cannot jump to ModuleInjector tree
26842
+ * ```
26843
+ *
26844
+ * ```
26845
+ * ┌───────┐ ┌───────────────────┐
26846
+ * ┌───────────┤ModuleA├───Injector────►│EnvironmentInjector│
26847
+ * │ └───┬───┘ └───────────────────┘
26848
+ * │ │
26849
+ * │ bootstraps
26850
+ * │ │
26851
+ * │ │
26852
+ * │ ┌────▼─────┐ ┌─────────────┐
26853
+ * declares │ComponentA├────Injector────►│NodeInjectorA│
26854
+ * │ └────┬─────┘ └─────▲───────┘
26855
+ * │ │ │
26856
+ * │ renders parent
26857
+ * │ │ │
26858
+ * │ ┌────▼─────┐ ┌─────┴───────┐
26859
+ * └─────────►│ComponentB├────Injector────►│NodeInjectorB│
26860
+ * └──────────┘ └─────────────┘
26861
+ *```
26862
+ *
26863
+ * @param injector an Injector to get the parent of
26864
+ * @returns Injector the parent of the given injector
26865
+ */
26866
+ function getInjectorParent(injector) {
26867
+ if (injector instanceof R3Injector) {
26868
+ return injector.parent;
26869
+ }
26870
+ let tNode;
26871
+ let lView;
26872
+ if (injector instanceof NodeInjector) {
26873
+ tNode = getNodeInjectorTNode(injector);
26874
+ lView = getNodeInjectorLView(injector);
26875
+ }
26876
+ else if (injector instanceof NullInjector) {
26877
+ return null;
26878
+ }
26879
+ else {
26880
+ throwError('getInjectorParent only support injectors of type R3Injector, NodeInjector, NullInjector');
26881
+ }
26882
+ const parentLocation = getParentInjectorLocation(tNode, lView);
26883
+ if (hasParentInjector(parentLocation)) {
26884
+ const parentInjectorIndex = getParentInjectorIndex(parentLocation);
26885
+ const parentLView = getParentInjectorView(parentLocation, lView);
26886
+ const parentTView = parentLView[TVIEW];
26887
+ const parentTNode = parentTView.data[parentInjectorIndex + 8 /* NodeInjectorOffset.TNODE */];
26888
+ return new NodeInjector(parentTNode, parentLView);
26889
+ }
26890
+ else {
26891
+ const chainedInjector = lView[INJECTOR$1];
26892
+ // Case where chainedInjector.injector is an OutletInjector and chainedInjector.injector.parent
26893
+ // is a NodeInjector.
26894
+ // todo(aleksanderbodurri): ideally nothing in packages/core should deal
26895
+ // directly with router concerns. Refactor this so that we can make the jump from
26896
+ // NodeInjector -> OutletInjector -> NodeInjector
26897
+ // without explictly relying on types contracts from packages/router
26898
+ const injectorParent = chainedInjector.injector?.parent;
26899
+ if (injectorParent instanceof NodeInjector) {
26900
+ return injectorParent;
26901
+ }
26902
+ }
26903
+ return null;
26904
+ }
26905
+ /**
26906
+ * Gets the module injector of a NodeInjector.
26907
+ *
26908
+ * @param injector NodeInjector to get module injector of
26909
+ * @returns Injector representing module injector of the given NodeInjector
26910
+ */
26911
+ function getModuleInjectorOfNodeInjector(injector) {
26912
+ let lView;
26913
+ if (injector instanceof NodeInjector) {
26914
+ lView = getNodeInjectorLView(injector);
26915
+ }
26916
+ else {
26917
+ throwError('getModuleInjectorOfNodeInjector must be called with a NodeInjector');
26918
+ }
26919
+ const chainedInjector = lView[INJECTOR$1];
26920
+ const moduleInjector = chainedInjector.parentInjector;
26921
+ if (!moduleInjector) {
26922
+ throwError('NodeInjector must have some connection to the module injector tree');
26923
+ }
26924
+ return moduleInjector;
26925
+ }
26926
+
25885
26927
  /**
25886
26928
  * This file introduces series of globally accessible debug tools
25887
26929
  * to allow for the Angular debugging story to function.
@@ -25907,6 +26949,10 @@ let _published = false;
25907
26949
  function publishDefaultGlobalUtils$1() {
25908
26950
  if (!_published) {
25909
26951
  _published = true;
26952
+ setupFrameworkInjectorProfiler();
26953
+ publishGlobalUtil('ɵgetDependenciesFromInjectable', getDependenciesFromInjectable);
26954
+ publishGlobalUtil('ɵgetInjectorProviders', getInjectorProviders);
26955
+ publishGlobalUtil('ɵgetInjectorResolutionPath', getInjectorResolutionPath);
25910
26956
  /**
25911
26957
  * Warning: this function is *INTERNAL* and should not be relied upon in application's code.
25912
26958
  * The contract of the function might be changed in any release and/or the function can be
@@ -29993,14 +31039,6 @@ function enableHydrationRuntimeSupport() {
29993
31039
  enableApplyRootElementTransformImpl();
29994
31040
  }
29995
31041
  }
29996
- /**
29997
- * Detects whether the code is invoked in a browser.
29998
- * Later on, this check should be replaced with a tree-shakable
29999
- * flag (e.g. `!isServer`).
30000
- */
30001
- function isBrowser() {
30002
- return inject(PLATFORM_ID) === 'browser';
30003
- }
30004
31042
  /**
30005
31043
  * Outputs a message with hydration stats into a console.
30006
31044
  */
@@ -30049,7 +31087,7 @@ function withDomHydration() {
30049
31087
  provide: IS_HYDRATION_DOM_REUSE_ENABLED,
30050
31088
  useFactory: () => {
30051
31089
  let isEnabled = true;
30052
- if (isBrowser()) {
31090
+ if (isPlatformBrowser()) {
30053
31091
  // On the client, verify that the server response contains
30054
31092
  // hydration annotations. Otherwise, keep hydration disabled.
30055
31093
  const transferState = inject(TransferState, { optional: true });
@@ -30079,7 +31117,7 @@ function withDomHydration() {
30079
31117
  // on the client. Moving forward, the `isBrowser` check should
30080
31118
  // be replaced with a tree-shakable alternative (e.g. `isServer`
30081
31119
  // flag).
30082
- if (isBrowser() && inject(IS_HYDRATION_DOM_REUSE_ENABLED)) {
31120
+ if (isPlatformBrowser() && inject(IS_HYDRATION_DOM_REUSE_ENABLED)) {
30083
31121
  enableHydrationRuntimeSupport();
30084
31122
  }
30085
31123
  },
@@ -30092,13 +31130,13 @@ function withDomHydration() {
30092
31130
  // environment and when hydration is configured properly.
30093
31131
  // On a server, an application is rendered from scratch,
30094
31132
  // so the host content needs to be empty.
30095
- return isBrowser() && inject(IS_HYDRATION_DOM_REUSE_ENABLED);
31133
+ return isPlatformBrowser() && inject(IS_HYDRATION_DOM_REUSE_ENABLED);
30096
31134
  }
30097
31135
  },
30098
31136
  {
30099
31137
  provide: APP_BOOTSTRAP_LISTENER,
30100
31138
  useFactory: () => {
30101
- if (isBrowser() && inject(IS_HYDRATION_DOM_REUSE_ENABLED)) {
31139
+ if (isPlatformBrowser() && inject(IS_HYDRATION_DOM_REUSE_ENABLED)) {
30102
31140
  const appRef = inject(ApplicationRef);
30103
31141
  const injector = inject(Injector);
30104
31142
  return () => {
@@ -30134,6 +31172,11 @@ function logWarningOnStableTimedout(time, console) {
30134
31172
  /**
30135
31173
  * Transforms a value (typically a string) to a boolean.
30136
31174
  * Intended to be used as a transform function of an input.
31175
+ *
31176
+ * @usageNotes
31177
+ * ```typescript
31178
+ * @Input({ transform: booleanAttribute }) status!: boolean;
31179
+ * ```
30137
31180
  * @param value Value to be transformed.
30138
31181
  *
30139
31182
  * @publicApi
@@ -30147,6 +31190,11 @@ function booleanAttribute(value) {
30147
31190
  * @param value Value to be transformed.
30148
31191
  * @param fallbackValue Value to use if the provided value can't be parsed as a number.
30149
31192
  *
31193
+ * @usageNotes
31194
+ * ```typescript
31195
+ * @Input({ transform: numberAttribute }) id!: number;
31196
+ * ```
31197
+ *
30150
31198
  * @publicApi
30151
31199
  */
30152
31200
  function numberAttribute(value, fallbackValue = NaN) {
@@ -30439,5 +31487,5 @@ if (typeof ngDevMode !== 'undefined' && ngDevMode) {
30439
31487
  * Generated bundle index. Do not edit.
30440
31488
  */
30441
31489
 
30442
- export { ANIMATION_MODULE_TYPE, APP_BOOTSTRAP_LISTENER, APP_ID, APP_INITIALIZER, ApplicationInitStatus, ApplicationModule, ApplicationRef, Attribute, COMPILER_OPTIONS, CSP_NONCE, CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, ChangeDetectorRef, Compiler, CompilerFactory, Component, ComponentFactory$1 as ComponentFactory, ComponentFactoryResolver$1 as ComponentFactoryResolver, ComponentRef$1 as ComponentRef, ContentChild, ContentChildren, DEFAULT_CURRENCY_CODE, DebugElement, DebugEventListener, DebugNode, DefaultIterableDiffer, DestroyRef, Directive, ENVIRONMENT_INITIALIZER, ElementRef, EmbeddedViewRef, EnvironmentInjector, ErrorHandler, EventEmitter, Host, HostBinding, HostListener, INJECTOR, Inject, InjectFlags, Injectable, InjectionToken, Injector, Input, IterableDiffers, KeyValueDiffers, LOCALE_ID, MissingTranslationStrategy, ModuleWithComponentFactories, NO_ERRORS_SCHEMA, NgModule, NgModuleFactory$1 as NgModuleFactory, NgModuleRef$1 as NgModuleRef, NgProbeToken, NgZone, Optional, Output, PACKAGE_ROOT_URL, PLATFORM_ID, PLATFORM_INITIALIZER, Pipe, PlatformRef, Query, QueryList, Renderer2, RendererFactory2, RendererStyleFlags2, Sanitizer, SecurityContext, Self, SimpleChange, SkipSelf, TRANSLATIONS, TRANSLATIONS_FORMAT, TemplateRef, Testability, TestabilityRegistry, TransferState, Type, VERSION, Version, ViewChild, ViewChildren, ViewContainerRef, ViewEncapsulation$1 as ViewEncapsulation, ViewRef, asNativeElements, assertInInjectionContext, assertPlatform, booleanAttribute, computed, createComponent, createEnvironmentInjector, createNgModule, createNgModuleRef, createPlatform, createPlatformFactory, defineInjectable, destroyPlatform, effect, enableProdMode, forwardRef, getDebugNode, getModuleFactory, getNgModuleById, getPlatform, importProvidersFrom, inject, isDevMode, isSignal, isStandalone, makeEnvironmentProviders, makeStateKey, mergeApplicationConfig, numberAttribute, platformCore, provideZoneChangeDetection, reflectComponentType, resolveForwardRef, runInInjectionContext, setTestabilityGetter, signal, untracked, ALLOW_MULTIPLE_PLATFORMS as ɵALLOW_MULTIPLE_PLATFORMS, ComponentFactory$1 as ɵComponentFactory, Console as ɵConsole, DEFAULT_LOCALE_ID as ɵDEFAULT_LOCALE_ID, ENABLED_SSR_FEATURES as ɵENABLED_SSR_FEATURES, INJECTOR_SCOPE as ɵINJECTOR_SCOPE, IS_HYDRATION_DOM_REUSE_ENABLED as ɵIS_HYDRATION_DOM_REUSE_ENABLED, InitialRenderPendingTasks as ɵInitialRenderPendingTasks, LContext as ɵLContext, LifecycleHooksFeature as ɵLifecycleHooksFeature, LocaleDataIndex as ɵLocaleDataIndex, NG_COMP_DEF as ɵNG_COMP_DEF, NG_DIR_DEF as ɵNG_DIR_DEF, NG_ELEMENT_ID as ɵNG_ELEMENT_ID, NG_INJ_DEF as ɵNG_INJ_DEF, NG_MOD_DEF as ɵNG_MOD_DEF, NG_PIPE_DEF as ɵNG_PIPE_DEF, NG_PROV_DEF as ɵNG_PROV_DEF, NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR as ɵNOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR, NO_CHANGE as ɵNO_CHANGE, NgModuleFactory as ɵNgModuleFactory, NoopNgZone as ɵNoopNgZone, ReflectionCapabilities as ɵReflectionCapabilities, ComponentFactory as ɵRender3ComponentFactory, ComponentRef as ɵRender3ComponentRef, NgModuleRef as ɵRender3NgModuleRef, RuntimeError as ɵRuntimeError, TESTABILITY as ɵTESTABILITY, TESTABILITY_GETTER as ɵTESTABILITY_GETTER, ViewRef$1 as ɵViewRef, XSS_SECURITY_URL as ɵXSS_SECURITY_URL, _sanitizeHtml as ɵ_sanitizeHtml, _sanitizeUrl as ɵ_sanitizeUrl, allowSanitizationBypassAndThrow as ɵallowSanitizationBypassAndThrow, annotateForHydration as ɵannotateForHydration, bypassSanitizationTrustHtml as ɵbypassSanitizationTrustHtml, bypassSanitizationTrustResourceUrl as ɵbypassSanitizationTrustResourceUrl, bypassSanitizationTrustScript as ɵbypassSanitizationTrustScript, bypassSanitizationTrustStyle as ɵbypassSanitizationTrustStyle, bypassSanitizationTrustUrl as ɵbypassSanitizationTrustUrl, clearResolutionOfComponentResourcesQueue as ɵclearResolutionOfComponentResourcesQueue, compileComponent as ɵcompileComponent, compileDirective as ɵcompileDirective, compileNgModule as ɵcompileNgModule, compileNgModuleDefs as ɵcompileNgModuleDefs, compileNgModuleFactory as ɵcompileNgModuleFactory, compilePipe as ɵcompilePipe, convertToBitFlags as ɵconvertToBitFlags, createInjector as ɵcreateInjector, defaultIterableDiffers as ɵdefaultIterableDiffers, defaultKeyValueDiffers as ɵdefaultKeyValueDiffers, detectChanges as ɵdetectChanges, devModeEqual as ɵdevModeEqual, findLocaleData as ɵfindLocaleData, flushModuleScopingQueueAsMuchAsPossible as ɵflushModuleScopingQueueAsMuchAsPossible, formatRuntimeError as ɵformatRuntimeError, getDebugNode as ɵgetDebugNode, getDirectives as ɵgetDirectives, getHostElement as ɵgetHostElement, getInjectableDef as ɵgetInjectableDef, getLContext as ɵgetLContext, getLocaleCurrencyCode as ɵgetLocaleCurrencyCode, getLocalePluralCase as ɵgetLocalePluralCase, getSanitizationBypassType as ɵgetSanitizationBypassType, ɵgetUnknownElementStrictMode, ɵgetUnknownPropertyStrictMode, _global as ɵglobal, injectChangeDetectorRef as ɵinjectChangeDetectorRef, internalCreateApplication as ɵinternalCreateApplication, isBoundToModule as ɵisBoundToModule, isEnvironmentProviders as ɵisEnvironmentProviders, isInjectable as ɵisInjectable, isNgModule as ɵisNgModule, isPromise as ɵisPromise, isSubscribable as ɵisSubscribable, noSideEffects as ɵnoSideEffects, patchComponentDefWithScope as ɵpatchComponentDefWithScope, publishDefaultGlobalUtils$1 as ɵpublishDefaultGlobalUtils, publishGlobalUtil as ɵpublishGlobalUtil, registerLocaleData as ɵregisterLocaleData, resetCompiledComponents as ɵresetCompiledComponents, resetJitOptions as ɵresetJitOptions, resolveComponentResources as ɵresolveComponentResources, setAllowDuplicateNgModuleIdsForTest as ɵsetAllowDuplicateNgModuleIdsForTest, setAlternateWeakRefImpl as ɵsetAlternateWeakRefImpl, setClassMetadata as ɵsetClassMetadata, setCurrentInjector as ɵsetCurrentInjector, setDocument as ɵsetDocument, setLocaleId as ɵsetLocaleId, ɵsetUnknownElementStrictMode, ɵsetUnknownPropertyStrictMode, store as ɵstore, stringify as ɵstringify, transitiveScopesFor as ɵtransitiveScopesFor, unregisterAllLocaleData as ɵunregisterLocaleData, unwrapSafeValue as ɵunwrapSafeValue, withDomHydration as ɵwithDomHydration, ɵɵCopyDefinitionFeature, FactoryTarget as ɵɵFactoryTarget, ɵɵHostDirectivesFeature, ɵɵInheritDefinitionFeature, ɵɵInputTransformsFeature, ɵɵNgOnChangesFeature, ɵɵProvidersFeature, ɵɵStandaloneFeature, ɵɵadvance, ɵɵattribute, ɵɵattributeInterpolate1, ɵɵattributeInterpolate2, ɵɵattributeInterpolate3, ɵɵattributeInterpolate4, ɵɵattributeInterpolate5, ɵɵattributeInterpolate6, ɵɵattributeInterpolate7, ɵɵattributeInterpolate8, ɵɵattributeInterpolateV, ɵɵclassMap, ɵɵclassMapInterpolate1, ɵɵclassMapInterpolate2, ɵɵclassMapInterpolate3, ɵɵclassMapInterpolate4, ɵɵclassMapInterpolate5, ɵɵclassMapInterpolate6, ɵɵclassMapInterpolate7, ɵɵclassMapInterpolate8, ɵɵclassMapInterpolateV, ɵɵclassProp, ɵɵcontentQuery, ɵɵdefineComponent, ɵɵdefineDirective, ɵɵdefineInjectable, ɵɵdefineInjector, ɵɵdefineNgModule, ɵɵdefinePipe, ɵɵdirectiveInject, ɵɵdisableBindings, ɵɵelement, ɵɵelementContainer, ɵɵelementContainerEnd, ɵɵelementContainerStart, ɵɵelementEnd, ɵɵelementStart, ɵɵenableBindings, ɵɵgetCurrentView, ɵɵgetInheritedFactory, ɵɵhostProperty, ɵɵi18n, ɵɵi18nApply, ɵɵi18nAttributes, ɵɵi18nEnd, ɵɵi18nExp, ɵɵi18nPostprocess, ɵɵi18nStart, ɵɵinject, ɵɵinjectAttribute, ɵɵinvalidFactory, ɵɵinvalidFactoryDep, ɵɵlistener, ɵɵloadQuery, ɵɵnamespaceHTML, ɵɵnamespaceMathML, ɵɵnamespaceSVG, ɵɵnextContext, ɵɵngDeclareClassMetadata, ɵɵngDeclareComponent, ɵɵngDeclareDirective, ɵɵngDeclareFactory, ɵɵngDeclareInjectable, ɵɵngDeclareInjector, ɵɵngDeclareNgModule, ɵɵngDeclarePipe, ɵɵpipe, ɵɵpipeBind1, ɵɵpipeBind2, ɵɵpipeBind3, ɵɵpipeBind4, ɵɵpipeBindV, ɵɵprojection, ɵɵprojectionDef, ɵɵproperty, ɵɵpropertyInterpolate, ɵɵpropertyInterpolate1, ɵɵpropertyInterpolate2, ɵɵpropertyInterpolate3, ɵɵpropertyInterpolate4, ɵɵpropertyInterpolate5, ɵɵpropertyInterpolate6, ɵɵpropertyInterpolate7, ɵɵpropertyInterpolate8, ɵɵpropertyInterpolateV, ɵɵpureFunction0, ɵɵpureFunction1, ɵɵpureFunction2, ɵɵpureFunction3, ɵɵpureFunction4, ɵɵpureFunction5, ɵɵpureFunction6, ɵɵpureFunction7, ɵɵpureFunction8, ɵɵpureFunctionV, ɵɵqueryRefresh, ɵɵreference, registerNgModuleType as ɵɵregisterNgModuleType, ɵɵresetView, ɵɵresolveBody, ɵɵresolveDocument, ɵɵresolveWindow, ɵɵrestoreView, ɵɵsanitizeHtml, ɵɵsanitizeResourceUrl, ɵɵsanitizeScript, ɵɵsanitizeStyle, ɵɵsanitizeUrl, ɵɵsanitizeUrlOrResourceUrl, ɵɵsetComponentScope, ɵɵsetNgModuleScope, ɵɵstyleMap, ɵɵstyleMapInterpolate1, ɵɵstyleMapInterpolate2, ɵɵstyleMapInterpolate3, ɵɵstyleMapInterpolate4, ɵɵstyleMapInterpolate5, ɵɵstyleMapInterpolate6, ɵɵstyleMapInterpolate7, ɵɵstyleMapInterpolate8, ɵɵstyleMapInterpolateV, ɵɵstyleProp, ɵɵstylePropInterpolate1, ɵɵstylePropInterpolate2, ɵɵstylePropInterpolate3, ɵɵstylePropInterpolate4, ɵɵstylePropInterpolate5, ɵɵstylePropInterpolate6, ɵɵstylePropInterpolate7, ɵɵstylePropInterpolate8, ɵɵstylePropInterpolateV, ɵɵsyntheticHostListener, ɵɵsyntheticHostProperty, ɵɵtemplate, ɵɵtemplateRefExtractor, ɵɵtext, ɵɵtextInterpolate, ɵɵtextInterpolate1, ɵɵtextInterpolate2, ɵɵtextInterpolate3, ɵɵtextInterpolate4, ɵɵtextInterpolate5, ɵɵtextInterpolate6, ɵɵtextInterpolate7, ɵɵtextInterpolate8, ɵɵtextInterpolateV, ɵɵtrustConstantHtml, ɵɵtrustConstantResourceUrl, ɵɵvalidateIframeAttribute, ɵɵviewQuery };
31490
+ export { ANIMATION_MODULE_TYPE, APP_BOOTSTRAP_LISTENER, APP_ID, APP_INITIALIZER, ApplicationInitStatus, ApplicationModule, ApplicationRef, Attribute, COMPILER_OPTIONS, CSP_NONCE, CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, ChangeDetectorRef, Compiler, CompilerFactory, Component, ComponentFactory$1 as ComponentFactory, ComponentFactoryResolver$1 as ComponentFactoryResolver, ComponentRef$1 as ComponentRef, ContentChild, ContentChildren, DEFAULT_CURRENCY_CODE, DebugElement, DebugEventListener, DebugNode, DefaultIterableDiffer, DestroyRef, Directive, ENVIRONMENT_INITIALIZER, ElementRef, EmbeddedViewRef, EnvironmentInjector, ErrorHandler, EventEmitter, Host, HostBinding, HostListener, INJECTOR, Inject, InjectFlags, Injectable, InjectionToken, Injector, Input, IterableDiffers, KeyValueDiffers, LOCALE_ID, MissingTranslationStrategy, ModuleWithComponentFactories, NO_ERRORS_SCHEMA, NgModule, NgModuleFactory$1 as NgModuleFactory, NgModuleRef$1 as NgModuleRef, NgProbeToken, NgZone, Optional, Output, PACKAGE_ROOT_URL, PLATFORM_ID, PLATFORM_INITIALIZER, Pipe, PlatformRef, Query, QueryList, Renderer2, RendererFactory2, RendererStyleFlags2, Sanitizer, SecurityContext, Self, SimpleChange, SkipSelf, TRANSLATIONS, TRANSLATIONS_FORMAT, TemplateRef, Testability, TestabilityRegistry, TransferState, Type, VERSION, Version, ViewChild, ViewChildren, ViewContainerRef, ViewEncapsulation$1 as ViewEncapsulation, ViewRef, afterNextRender, afterRender, asNativeElements, assertInInjectionContext, assertPlatform, booleanAttribute, computed, createComponent, createEnvironmentInjector, createNgModule, createNgModuleRef, createPlatform, createPlatformFactory, defineInjectable, destroyPlatform, effect, enableProdMode, forwardRef, getDebugNode, getModuleFactory, getNgModuleById, getPlatform, importProvidersFrom, inject, isDevMode, isSignal, isStandalone, makeEnvironmentProviders, makeStateKey, mergeApplicationConfig, numberAttribute, platformCore, provideZoneChangeDetection, reflectComponentType, resolveForwardRef, runInInjectionContext, setTestabilityGetter, signal, untracked, ALLOW_MULTIPLE_PLATFORMS as ɵALLOW_MULTIPLE_PLATFORMS, AfterRenderEventManager as ɵAfterRenderEventManager, ComponentFactory$1 as ɵComponentFactory, Console as ɵConsole, DEFAULT_LOCALE_ID as ɵDEFAULT_LOCALE_ID, ENABLED_SSR_FEATURES as ɵENABLED_SSR_FEATURES, INJECTOR_SCOPE as ɵINJECTOR_SCOPE, IS_HYDRATION_DOM_REUSE_ENABLED as ɵIS_HYDRATION_DOM_REUSE_ENABLED, InitialRenderPendingTasks as ɵInitialRenderPendingTasks, LContext as ɵLContext, LifecycleHooksFeature as ɵLifecycleHooksFeature, LocaleDataIndex as ɵLocaleDataIndex, NG_COMP_DEF as ɵNG_COMP_DEF, NG_DIR_DEF as ɵNG_DIR_DEF, NG_ELEMENT_ID as ɵNG_ELEMENT_ID, NG_INJ_DEF as ɵNG_INJ_DEF, NG_MOD_DEF as ɵNG_MOD_DEF, NG_PIPE_DEF as ɵNG_PIPE_DEF, NG_PROV_DEF as ɵNG_PROV_DEF, NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR as ɵNOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR, NO_CHANGE as ɵNO_CHANGE, NgModuleFactory as ɵNgModuleFactory, NoopNgZone as ɵNoopNgZone, ReflectionCapabilities as ɵReflectionCapabilities, ComponentFactory as ɵRender3ComponentFactory, ComponentRef as ɵRender3ComponentRef, NgModuleRef as ɵRender3NgModuleRef, RuntimeError as ɵRuntimeError, TESTABILITY as ɵTESTABILITY, TESTABILITY_GETTER as ɵTESTABILITY_GETTER, ViewRef$1 as ɵViewRef, XSS_SECURITY_URL as ɵXSS_SECURITY_URL, _sanitizeHtml as ɵ_sanitizeHtml, _sanitizeUrl as ɵ_sanitizeUrl, allowSanitizationBypassAndThrow as ɵallowSanitizationBypassAndThrow, annotateForHydration as ɵannotateForHydration, bypassSanitizationTrustHtml as ɵbypassSanitizationTrustHtml, bypassSanitizationTrustResourceUrl as ɵbypassSanitizationTrustResourceUrl, bypassSanitizationTrustScript as ɵbypassSanitizationTrustScript, bypassSanitizationTrustStyle as ɵbypassSanitizationTrustStyle, bypassSanitizationTrustUrl as ɵbypassSanitizationTrustUrl, clearResolutionOfComponentResourcesQueue as ɵclearResolutionOfComponentResourcesQueue, compileComponent as ɵcompileComponent, compileDirective as ɵcompileDirective, compileNgModule as ɵcompileNgModule, compileNgModuleDefs as ɵcompileNgModuleDefs, compileNgModuleFactory as ɵcompileNgModuleFactory, compilePipe as ɵcompilePipe, convertToBitFlags as ɵconvertToBitFlags, createInjector as ɵcreateInjector, defaultIterableDiffers as ɵdefaultIterableDiffers, defaultKeyValueDiffers as ɵdefaultKeyValueDiffers, detectChanges as ɵdetectChanges, devModeEqual as ɵdevModeEqual, findLocaleData as ɵfindLocaleData, flushModuleScopingQueueAsMuchAsPossible as ɵflushModuleScopingQueueAsMuchAsPossible, formatRuntimeError as ɵformatRuntimeError, getDebugNode as ɵgetDebugNode, getDirectives as ɵgetDirectives, getHostElement as ɵgetHostElement, getInjectableDef as ɵgetInjectableDef, getLContext as ɵgetLContext, getLocaleCurrencyCode as ɵgetLocaleCurrencyCode, getLocalePluralCase as ɵgetLocalePluralCase, getSanitizationBypassType as ɵgetSanitizationBypassType, ɵgetUnknownElementStrictMode, ɵgetUnknownPropertyStrictMode, _global as ɵglobal, injectChangeDetectorRef as ɵinjectChangeDetectorRef, internalCreateApplication as ɵinternalCreateApplication, isBoundToModule as ɵisBoundToModule, isEnvironmentProviders as ɵisEnvironmentProviders, isInjectable as ɵisInjectable, isNgModule as ɵisNgModule, isPromise as ɵisPromise, isSubscribable as ɵisSubscribable, noSideEffects as ɵnoSideEffects, patchComponentDefWithScope as ɵpatchComponentDefWithScope, publishDefaultGlobalUtils$1 as ɵpublishDefaultGlobalUtils, publishGlobalUtil as ɵpublishGlobalUtil, registerLocaleData as ɵregisterLocaleData, resetCompiledComponents as ɵresetCompiledComponents, resetJitOptions as ɵresetJitOptions, resolveComponentResources as ɵresolveComponentResources, setAllowDuplicateNgModuleIdsForTest as ɵsetAllowDuplicateNgModuleIdsForTest, setAlternateWeakRefImpl as ɵsetAlternateWeakRefImpl, setClassMetadata as ɵsetClassMetadata, setCurrentInjector as ɵsetCurrentInjector, setDocument as ɵsetDocument, setInjectorProfilerContext as ɵsetInjectorProfilerContext, setLocaleId as ɵsetLocaleId, ɵsetUnknownElementStrictMode, ɵsetUnknownPropertyStrictMode, store as ɵstore, stringify as ɵstringify, transitiveScopesFor as ɵtransitiveScopesFor, unregisterAllLocaleData as ɵunregisterLocaleData, unwrapSafeValue as ɵunwrapSafeValue, withDomHydration as ɵwithDomHydration, ɵɵCopyDefinitionFeature, FactoryTarget as ɵɵFactoryTarget, ɵɵHostDirectivesFeature, ɵɵInheritDefinitionFeature, ɵɵInputTransformsFeature, ɵɵNgOnChangesFeature, ɵɵProvidersFeature, ɵɵStandaloneFeature, ɵɵadvance, ɵɵattribute, ɵɵattributeInterpolate1, ɵɵattributeInterpolate2, ɵɵattributeInterpolate3, ɵɵattributeInterpolate4, ɵɵattributeInterpolate5, ɵɵattributeInterpolate6, ɵɵattributeInterpolate7, ɵɵattributeInterpolate8, ɵɵattributeInterpolateV, ɵɵclassMap, ɵɵclassMapInterpolate1, ɵɵclassMapInterpolate2, ɵɵclassMapInterpolate3, ɵɵclassMapInterpolate4, ɵɵclassMapInterpolate5, ɵɵclassMapInterpolate6, ɵɵclassMapInterpolate7, ɵɵclassMapInterpolate8, ɵɵclassMapInterpolateV, ɵɵclassProp, ɵɵcontentQuery, ɵɵdefer, ɵɵdefineComponent, ɵɵdefineDirective, ɵɵdefineInjectable, ɵɵdefineInjector, ɵɵdefineNgModule, ɵɵdefinePipe, ɵɵdirectiveInject, ɵɵdisableBindings, ɵɵelement, ɵɵelementContainer, ɵɵelementContainerEnd, ɵɵelementContainerStart, ɵɵelementEnd, ɵɵelementStart, ɵɵenableBindings, ɵɵgetCurrentView, ɵɵgetInheritedFactory, ɵɵhostProperty, ɵɵi18n, ɵɵi18nApply, ɵɵi18nAttributes, ɵɵi18nEnd, ɵɵi18nExp, ɵɵi18nPostprocess, ɵɵi18nStart, ɵɵinject, ɵɵinjectAttribute, ɵɵinvalidFactory, ɵɵinvalidFactoryDep, ɵɵlistener, ɵɵloadQuery, ɵɵnamespaceHTML, ɵɵnamespaceMathML, ɵɵnamespaceSVG, ɵɵnextContext, ɵɵngDeclareClassMetadata, ɵɵngDeclareComponent, ɵɵngDeclareDirective, ɵɵngDeclareFactory, ɵɵngDeclareInjectable, ɵɵngDeclareInjector, ɵɵngDeclareNgModule, ɵɵngDeclarePipe, ɵɵpipe, ɵɵpipeBind1, ɵɵpipeBind2, ɵɵpipeBind3, ɵɵpipeBind4, ɵɵpipeBindV, ɵɵprojection, ɵɵprojectionDef, ɵɵproperty, ɵɵpropertyInterpolate, ɵɵpropertyInterpolate1, ɵɵpropertyInterpolate2, ɵɵpropertyInterpolate3, ɵɵpropertyInterpolate4, ɵɵpropertyInterpolate5, ɵɵpropertyInterpolate6, ɵɵpropertyInterpolate7, ɵɵpropertyInterpolate8, ɵɵpropertyInterpolateV, ɵɵpureFunction0, ɵɵpureFunction1, ɵɵpureFunction2, ɵɵpureFunction3, ɵɵpureFunction4, ɵɵpureFunction5, ɵɵpureFunction6, ɵɵpureFunction7, ɵɵpureFunction8, ɵɵpureFunctionV, ɵɵqueryRefresh, ɵɵreference, registerNgModuleType as ɵɵregisterNgModuleType, ɵɵresetView, ɵɵresolveBody, ɵɵresolveDocument, ɵɵresolveWindow, ɵɵrestoreView, ɵɵsanitizeHtml, ɵɵsanitizeResourceUrl, ɵɵsanitizeScript, ɵɵsanitizeStyle, ɵɵsanitizeUrl, ɵɵsanitizeUrlOrResourceUrl, ɵɵsetComponentScope, ɵɵsetNgModuleScope, ɵɵstyleMap, ɵɵstyleMapInterpolate1, ɵɵstyleMapInterpolate2, ɵɵstyleMapInterpolate3, ɵɵstyleMapInterpolate4, ɵɵstyleMapInterpolate5, ɵɵstyleMapInterpolate6, ɵɵstyleMapInterpolate7, ɵɵstyleMapInterpolate8, ɵɵstyleMapInterpolateV, ɵɵstyleProp, ɵɵstylePropInterpolate1, ɵɵstylePropInterpolate2, ɵɵstylePropInterpolate3, ɵɵstylePropInterpolate4, ɵɵstylePropInterpolate5, ɵɵstylePropInterpolate6, ɵɵstylePropInterpolate7, ɵɵstylePropInterpolate8, ɵɵstylePropInterpolateV, ɵɵsyntheticHostListener, ɵɵsyntheticHostProperty, ɵɵtemplate, ɵɵtemplateRefExtractor, ɵɵtext, ɵɵtextInterpolate, ɵɵtextInterpolate1, ɵɵtextInterpolate2, ɵɵtextInterpolate3, ɵɵtextInterpolate4, ɵɵtextInterpolate5, ɵɵtextInterpolate6, ɵɵtextInterpolate7, ɵɵtextInterpolate8, ɵɵtextInterpolateV, ɵɵtrustConstantHtml, ɵɵtrustConstantResourceUrl, ɵɵvalidateIframeAttribute, ɵɵviewQuery };
30443
31491
  //# sourceMappingURL=core.mjs.map