@angular/core 16.2.0-next.4 → 16.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/esm2022/src/application_tokens.mjs +2 -1
  2. package/esm2022/src/core.mjs +2 -1
  3. package/esm2022/src/core_private_export.mjs +3 -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/provider_collection.mjs +17 -16
  10. package/esm2022/src/di/r3_injector.mjs +37 -2
  11. package/esm2022/src/errors.mjs +1 -1
  12. package/esm2022/src/hydration/annotate.mjs +60 -15
  13. package/esm2022/src/hydration/api.mjs +40 -17
  14. package/esm2022/src/hydration/cleanup.mjs +15 -6
  15. package/esm2022/src/hydration/utils.mjs +58 -20
  16. package/esm2022/src/linker/template_ref.mjs +4 -19
  17. package/esm2022/src/linker/view_container_ref.mjs +5 -13
  18. package/esm2022/src/metadata/directives.mjs +1 -1
  19. package/esm2022/src/render3/after_render_hooks.mjs +210 -0
  20. package/esm2022/src/render3/component_ref.mjs +11 -11
  21. package/esm2022/src/render3/debug/framework_injector_profiler.mjs +212 -0
  22. package/esm2022/src/render3/debug/injector_profiler.mjs +103 -0
  23. package/esm2022/src/render3/di.mjs +32 -2
  24. package/esm2022/src/render3/di_setup.mjs +11 -4
  25. package/esm2022/src/render3/hooks.mjs +3 -3
  26. package/esm2022/src/render3/index.mjs +2 -2
  27. package/esm2022/src/render3/instructions/all.mjs +2 -1
  28. package/esm2022/src/render3/instructions/change_detection.mjs +16 -9
  29. package/esm2022/src/render3/instructions/defer.mjs +19 -0
  30. package/esm2022/src/render3/instructions/di.mjs +5 -2
  31. package/esm2022/src/render3/instructions/shared.mjs +1 -1
  32. package/esm2022/src/render3/interfaces/view.mjs +1 -1
  33. package/esm2022/src/render3/jit/environment.mjs +2 -1
  34. package/esm2022/src/render3/node_manipulation.mjs +5 -5
  35. package/esm2022/src/render3/pipe.mjs +12 -3
  36. package/esm2022/src/render3/util/global_utils.mjs +7 -1
  37. package/esm2022/src/render3/util/injector_discovery_utils.mjs +460 -0
  38. package/esm2022/src/render3/util/misc_utils.mjs +12 -1
  39. package/esm2022/src/render3/view_manipulation.mjs +65 -0
  40. package/esm2022/src/render3/view_ref.mjs +3 -3
  41. package/esm2022/src/util/coercion.mjs +11 -1
  42. package/esm2022/src/version.mjs +1 -1
  43. package/esm2022/testing/src/logger.mjs +3 -3
  44. package/fesm2022/core.mjs +1854 -650
  45. package/fesm2022/core.mjs.map +1 -1
  46. package/fesm2022/rxjs-interop.mjs +1 -1
  47. package/fesm2022/rxjs-interop.mjs.map +1 -1
  48. package/fesm2022/testing.mjs +4023 -3540
  49. package/fesm2022/testing.mjs.map +1 -1
  50. package/index.d.ts +214 -10
  51. package/package.json +1 -1
  52. package/rxjs-interop/index.d.ts +1 -1
  53. package/schematics/migrations/guard-and-resolve-interfaces/bundle.js +13 -13
  54. package/schematics/migrations/remove-module-id/bundle.js +14 -14
  55. package/schematics/ng-generate/standalone-migration/bundle.js +3664 -2727
  56. package/schematics/ng-generate/standalone-migration/bundle.js.map +4 -4
  57. 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.4
2
+ * @license Angular v16.2.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;
@@ -6812,7 +6937,7 @@ function createElementNode(renderer, name, namespace) {
6812
6937
  * @param tView The `TView' of the `LView` from which elements should be added or removed
6813
6938
  * @param lView The view from which elements should be added or removed
6814
6939
  */
6815
- function removeViewFromContainer(tView, lView) {
6940
+ function removeViewFromDOM(tView, lView) {
6816
6941
  const renderer = lView[RENDERER];
6817
6942
  applyView(tView, lView, renderer, 2 /* WalkTNodeTreeAction.Detach */, null, null);
6818
6943
  lView[HOST] = null;
@@ -6832,7 +6957,7 @@ function removeViewFromContainer(tView, lView) {
6832
6957
  * @param parentNativeNode The parent `RElement` where it should be inserted into.
6833
6958
  * @param beforeNode The node before which elements should be added, if insert mode
6834
6959
  */
6835
- function addViewToContainer(tView, parentTNode, renderer, lView, parentNativeNode, beforeNode) {
6960
+ function addViewToDOM(tView, parentTNode, renderer, lView, parentNativeNode, beforeNode) {
6836
6961
  lView[HOST] = parentNativeNode;
6837
6962
  lView[T_HOST] = parentTNode;
6838
6963
  applyView(tView, lView, renderer, 1 /* WalkTNodeTreeAction.Insert */, parentNativeNode, beforeNode);
@@ -6843,7 +6968,7 @@ function addViewToContainer(tView, parentTNode, renderer, lView, parentNativeNod
6843
6968
  * @param tView The `TView' of the `LView` to be detached
6844
6969
  * @param lView the `LView` to be detached.
6845
6970
  */
6846
- function renderDetachView(tView, lView) {
6971
+ function detachViewFromDOM(tView, lView) {
6847
6972
  applyView(tView, lView, lView[RENDERER], 2 /* WalkTNodeTreeAction.Detach */, null, null);
6848
6973
  }
6849
6974
  /**
@@ -7005,7 +7130,7 @@ function detachView(lContainer, removeIndex) {
7005
7130
  lContainer[indexInContainer - 1][NEXT] = viewToDetach[NEXT];
7006
7131
  }
7007
7132
  const removedLView = removeFromArray(lContainer, CONTAINER_HEADER_OFFSET + removeIndex);
7008
- removeViewFromContainer(viewToDetach[TVIEW], viewToDetach);
7133
+ removeViewFromDOM(viewToDetach[TVIEW], viewToDetach);
7009
7134
  // notify query that a view has been removed
7010
7135
  const lQueries = removedLView[QUERIES];
7011
7136
  if (lQueries !== null) {
@@ -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);
@@ -9489,6 +9649,7 @@ const PLATFORM_ID = new InjectionToken('Platform ID', {
9489
9649
  * A [DI token](guide/glossary#di-token "DI token definition") that indicates the root directory of
9490
9650
  * the application
9491
9651
  * @publicApi
9652
+ * @deprecated
9492
9653
  */
9493
9654
  const PACKAGE_ROOT_URL = new InjectionToken('Application Packages Root URL');
9494
9655
  // We keep this token here, rather than the animations package, so that modules that only care
@@ -9709,6 +9870,10 @@ const NGH_DATA_KEY = makeStateKey(TRANSFER_STATE_TOKEN_ID);
9709
9870
  * state that contains the necessary hydration info for this component.
9710
9871
  */
9711
9872
  const NGH_ATTR_NAME = 'ngh';
9873
+ /**
9874
+ * Marker used in a comment node to ensure hydration content integrity
9875
+ */
9876
+ const SSR_CONTENT_INTEGRITY_MARKER = 'nghm';
9712
9877
  /**
9713
9878
  * Reference to a function that reads `ngh` attribute value from a given RNode
9714
9879
  * and retrieves hydration information from the TransferState using that value
@@ -9716,12 +9881,30 @@ const NGH_ATTR_NAME = 'ngh';
9716
9881
  *
9717
9882
  * @param rNode Component's host element.
9718
9883
  * @param injector Injector that this component has access to.
9884
+ * @param isRootView Specifies whether we trying to read hydration info for the root view.
9719
9885
  */
9720
- let _retrieveHydrationInfoImpl = (rNode, injector) => null;
9721
- function retrieveHydrationInfoImpl(rNode, injector) {
9722
- const nghAttrValue = rNode.getAttribute(NGH_ATTR_NAME);
9886
+ let _retrieveHydrationInfoImpl = (rNode, injector, isRootView) => null;
9887
+ function retrieveHydrationInfoImpl(rNode, injector, isRootView = false) {
9888
+ let nghAttrValue = rNode.getAttribute(NGH_ATTR_NAME);
9723
9889
  if (nghAttrValue == null)
9724
9890
  return null;
9891
+ // For cases when a root component also acts as an anchor node for a ViewContainerRef
9892
+ // (for example, when ViewContainerRef is injected in a root component), there is a need
9893
+ // to serialize information about the component itself, as well as an LContainer that
9894
+ // represents this ViewContainerRef. Effectively, we need to serialize 2 pieces of info:
9895
+ // (1) hydration info for the root component itself and (2) hydration info for the
9896
+ // ViewContainerRef instance (an LContainer). Each piece of information is included into
9897
+ // the hydration data (in the TransferState object) separately, thus we end up with 2 ids.
9898
+ // Since we only have 1 root element, we encode both bits of info into a single string:
9899
+ // ids are separated by the `|` char (e.g. `10|25`, where `10` is the ngh for a component view
9900
+ // and 25 is the `ngh` for a root view which holds LContainer).
9901
+ const [componentViewNgh, rootViewNgh] = nghAttrValue.split('|');
9902
+ nghAttrValue = isRootView ? rootViewNgh : componentViewNgh;
9903
+ if (!nghAttrValue)
9904
+ return null;
9905
+ // We've read one of the ngh ids, keep the remaining one, so that
9906
+ // we can set it back on the DOM element.
9907
+ const remainingNgh = isRootView ? componentViewNgh : (rootViewNgh ? `|${rootViewNgh}` : '');
9725
9908
  let data = {};
9726
9909
  // An element might have an empty `ngh` attribute value (e.g. `<comp ngh="" />`),
9727
9910
  // which means that no special annotations are required. Do not attempt to read
@@ -9743,9 +9926,29 @@ function retrieveHydrationInfoImpl(rNode, injector) {
9743
9926
  data,
9744
9927
  firstChild: rNode.firstChild ?? null,
9745
9928
  };
9746
- // The `ngh` attribute is cleared from the DOM node now
9747
- // that the data has been retrieved.
9748
- rNode.removeAttribute(NGH_ATTR_NAME);
9929
+ if (isRootView) {
9930
+ // If there is hydration info present for the root view, it means that there was
9931
+ // a ViewContainerRef injected in the root component. The root component host element
9932
+ // acted as an anchor node in this scenario. As a result, the DOM nodes that represent
9933
+ // embedded views in this ViewContainerRef are located as siblings to the host node,
9934
+ // i.e. `<app-root /><#VIEW1><#VIEW2>...<!--container-->`. In this case, the current
9935
+ // node becomes the first child of this root view and the next sibling is the first
9936
+ // element in the DOM segment.
9937
+ dehydratedView.firstChild = rNode;
9938
+ // We use `0` here, since this is the slot (right after the HEADER_OFFSET)
9939
+ // where a component LView or an LContainer is located in a root LView.
9940
+ setSegmentHead(dehydratedView, 0, rNode.nextSibling);
9941
+ }
9942
+ if (remainingNgh) {
9943
+ // If we have only used one of the ngh ids, store the remaining one
9944
+ // back on this RNode.
9945
+ rNode.setAttribute(NGH_ATTR_NAME, remainingNgh);
9946
+ }
9947
+ else {
9948
+ // The `ngh` attribute is cleared from the DOM node now
9949
+ // that the data has been retrieved for all indices.
9950
+ rNode.removeAttribute(NGH_ATTR_NAME);
9951
+ }
9749
9952
  // Note: don't check whether this node was claimed for hydration,
9750
9953
  // because this node might've been previously claimed while processing
9751
9954
  // template instructions.
@@ -9763,14 +9966,16 @@ function enableRetrieveHydrationInfoImpl() {
9763
9966
  * Retrieves hydration info by reading the value from the `ngh` attribute
9764
9967
  * and accessing a corresponding slot in TransferState storage.
9765
9968
  */
9766
- function retrieveHydrationInfo(rNode, injector) {
9767
- return _retrieveHydrationInfoImpl(rNode, injector);
9969
+ function retrieveHydrationInfo(rNode, injector, isRootView = false) {
9970
+ return _retrieveHydrationInfoImpl(rNode, injector, isRootView);
9768
9971
  }
9769
9972
  /**
9770
- * Retrieves an instance of a component LView from a given ViewRef.
9771
- * Returns an instance of a component LView or `null` in case of an embedded view.
9973
+ * Retrieves the necessary object from a given ViewRef to serialize:
9974
+ * - an LView for component views
9975
+ * - an LContainer for cases when component acts as a ViewContainerRef anchor
9976
+ * - `null` in case of an embedded view
9772
9977
  */
9773
- function getComponentLViewForHydration(viewRef) {
9978
+ function getLNodeForHydration(viewRef) {
9774
9979
  // Reading an internal field from `ViewRef` instance.
9775
9980
  let lView = viewRef._lView;
9776
9981
  const tView = lView[TVIEW];
@@ -9784,12 +9989,6 @@ function getComponentLViewForHydration(viewRef) {
9784
9989
  if (isRootView(lView)) {
9785
9990
  lView = lView[HEADER_OFFSET];
9786
9991
  }
9787
- // If a `ViewContainerRef` was injected in a component class, this resulted
9788
- // in an LContainer creation at that location. In this case, the component
9789
- // LView is in the LContainer's `HOST` slot.
9790
- if (isLContainer(lView)) {
9791
- lView = lView[HOST];
9792
- }
9793
9992
  return lView;
9794
9993
  }
9795
9994
  function getTextNodeContent(node) {
@@ -10092,7 +10291,7 @@ class Version {
10092
10291
  /**
10093
10292
  * @publicApi
10094
10293
  */
10095
- const VERSION = new Version('16.2.0-next.4');
10294
+ const VERSION = new Version('16.2.0');
10096
10295
 
10097
10296
  // This default value is when checking the hierarchy for a token.
10098
10297
  //
@@ -10114,171 +10313,658 @@ const VERSION = new Version('16.2.0-next.4');
10114
10313
  const NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR = {};
10115
10314
 
10116
10315
  /**
10117
- * Marks current view and all ancestors dirty.
10118
- *
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.
10123
- *
10124
- * @param lView The starting LView to mark dirty
10125
- * @returns the root LView
10126
- */
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;
10137
- }
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
- }
10151
-
10152
- /**
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
- * }
10316
+ * Runs the given function in the [context](guide/dependency-injection-context) of the given
10317
+ * `Injector`.
10168
10318
  *
10169
- * @NgModule({
10170
- * providers: [{provide: ErrorHandler, useClass: MyErrorHandler}]
10171
- * })
10172
- * class MyModule {}
10173
- * ```
10319
+ * Within the function's stack frame, [`inject`](api/core/inject) can be used to inject dependencies
10320
+ * from the given `Injector`. Note that `inject` is only usable synchronously, and cannot be used in
10321
+ * any asynchronous callbacks or after any `await` points.
10174
10322
  *
10323
+ * @param injector the injector which will satisfy calls to [`inject`](api/core/inject) while `fn`
10324
+ * is executing
10325
+ * @param fn the closure to be run in the context of `injector`
10326
+ * @returns the return value of the function, if any
10175
10327
  * @publicApi
10176
10328
  */
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
- }
10329
+ function runInInjectionContext(injector, fn) {
10330
+ if (injector instanceof R3Injector) {
10331
+ injector.assertNotDestroyed();
10190
10332
  }
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;
10333
+ let prevInjectorProfilerContext;
10334
+ if (ngDevMode) {
10335
+ prevInjectorProfilerContext = setInjectorProfilerContext({ injector, token: null });
10198
10336
  }
10199
- }
10200
-
10201
- /**
10202
- * Internal token that specifies whether DOM reuse logic
10203
- * during hydration is enabled.
10204
- */
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;
10209
- /**
10210
- * Internal token that indicates whether host element content should be
10211
- * retained during the bootstrap.
10212
- */
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) {
10337
+ const prevInjector = setCurrentInjector(injector);
10338
+ const previousInjectImplementation = setInjectImplementation(undefined);
10228
10339
  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;
10340
+ return fn();
10231
10341
  }
10232
- catch (e) {
10233
- return '[ERROR] Exception while trying to serialize the value';
10342
+ finally {
10343
+ setCurrentInjector(prevInjector);
10344
+ ngDevMode && setInjectorProfilerContext(prevInjectorProfilerContext);
10345
+ setInjectImplementation(previousInjectImplementation);
10234
10346
  }
10235
10347
  }
10236
-
10237
- /**
10238
- *
10239
- * @codeGenApi
10240
- */
10241
- function ɵɵresolveWindow(element) {
10242
- return element.ownerDocument.defaultView;
10243
- }
10244
10348
  /**
10349
+ * Asserts that the current stack frame is within an [injection
10350
+ * context](guide/dependency-injection-context) and has access to `inject`.
10245
10351
  *
10246
- * @codeGenApi
10247
- */
10248
- function ɵɵresolveDocument(element) {
10249
- return element.ownerDocument;
10250
- }
10251
- /**
10352
+ * @param debugFn a reference to the function making the assertion (used for the error message).
10252
10353
  *
10253
- * @codeGenApi
10354
+ * @publicApi
10254
10355
  */
10255
- function ɵɵresolveBody(element) {
10256
- return element.ownerDocument.body;
10356
+ function assertInInjectionContext(debugFn) {
10357
+ // Taking a `Function` instead of a string name here prevents the unminified name of the function
10358
+ // from being retained in the bundle regardless of minification.
10359
+ if (!getInjectImplementation() && !getCurrentInjector()) {
10360
+ throw new RuntimeError(-203 /* RuntimeErrorCode.MISSING_INJECTION_CONTEXT */, ngDevMode &&
10361
+ (debugFn.name +
10362
+ '() can only be used within an injection context such as a constructor, a factory function, a field initializer, or a function used with `runInInjectionContext`'));
10363
+ }
10257
10364
  }
10365
+
10258
10366
  /**
10259
- * The special delimiter we use to separate property names, prefixes, and suffixes
10260
- * in property binding metadata. See storeBindingMetadata().
10261
- *
10262
- * We intentionally use the Unicode "REPLACEMENT CHARACTER" (U+FFFD) as a delimiter
10263
- * because it is a very uncommon character that is unlikely to be part of a user's
10264
- * property names or interpolation strings. If it is in fact used in a property
10265
- * binding, DebugElement.properties will not return the correct value for that
10266
- * binding. However, there should be no runtime effect for real applications.
10267
- *
10268
- * This character is typically rendered as a question mark inside of a diamond.
10269
- * See https://en.wikipedia.org/wiki/Specials_(Unicode_block)
10367
+ * A mapping of the @angular/core API surface used in generated expressions to the actual symbols.
10270
10368
  *
10369
+ * This should be kept up to date with the public exports of @angular/core.
10271
10370
  */
10272
- const INTERPOLATION_DELIMITER = `�`;
10371
+ const angularCoreDiEnv = {
10372
+ 'ɵɵdefineInjectable': ɵɵdefineInjectable,
10373
+ 'ɵɵdefineInjector': ɵɵdefineInjector,
10374
+ 'ɵɵinject': ɵɵinject,
10375
+ 'ɵɵinvalidFactoryDep': ɵɵinvalidFactoryDep,
10376
+ 'resolveForwardRef': resolveForwardRef,
10377
+ };
10378
+
10273
10379
  /**
10274
- * Unwrap a value which might be behind a closure (for forward declaration reasons).
10380
+ * Compile an Angular injectable according to its `Injectable` metadata, and patch the resulting
10381
+ * injectable def (`ɵprov`) onto the injectable type.
10275
10382
  */
10276
- function maybeUnwrapFn(value) {
10383
+ function compileInjectable(type, meta) {
10384
+ let ngInjectableDef = null;
10385
+ let ngFactoryDef = null;
10386
+ // if NG_PROV_DEF is already defined on this class then don't overwrite it
10387
+ if (!type.hasOwnProperty(NG_PROV_DEF)) {
10388
+ Object.defineProperty(type, NG_PROV_DEF, {
10389
+ get: () => {
10390
+ if (ngInjectableDef === null) {
10391
+ const compiler = getCompilerFacade({ usage: 0 /* JitCompilerUsage.Decorator */, kind: 'injectable', type });
10392
+ ngInjectableDef = compiler.compileInjectable(angularCoreDiEnv, `ng:///${type.name}/ɵprov.js`, getInjectableMetadata(type, meta));
10393
+ }
10394
+ return ngInjectableDef;
10395
+ },
10396
+ });
10397
+ }
10398
+ // if NG_FACTORY_DEF is already defined on this class then don't overwrite it
10399
+ if (!type.hasOwnProperty(NG_FACTORY_DEF)) {
10400
+ Object.defineProperty(type, NG_FACTORY_DEF, {
10401
+ get: () => {
10402
+ if (ngFactoryDef === null) {
10403
+ const compiler = getCompilerFacade({ usage: 0 /* JitCompilerUsage.Decorator */, kind: 'injectable', type });
10404
+ ngFactoryDef = compiler.compileFactory(angularCoreDiEnv, `ng:///${type.name}/ɵfac.js`, {
10405
+ name: type.name,
10406
+ type,
10407
+ typeArgumentCount: 0,
10408
+ deps: reflectDependencies(type),
10409
+ target: compiler.FactoryTarget.Injectable
10410
+ });
10411
+ }
10412
+ return ngFactoryDef;
10413
+ },
10414
+ // Leave this configurable so that the factories from directives or pipes can take precedence.
10415
+ configurable: true
10416
+ });
10417
+ }
10418
+ }
10419
+ const USE_VALUE = getClosureSafeProperty({ provide: String, useValue: getClosureSafeProperty });
10420
+ function isUseClassProvider(meta) {
10421
+ return meta.useClass !== undefined;
10422
+ }
10423
+ function isUseValueProvider(meta) {
10424
+ return USE_VALUE in meta;
10425
+ }
10426
+ function isUseFactoryProvider(meta) {
10427
+ return meta.useFactory !== undefined;
10428
+ }
10429
+ function isUseExistingProvider(meta) {
10430
+ return meta.useExisting !== undefined;
10431
+ }
10432
+ function getInjectableMetadata(type, srcMeta) {
10433
+ // Allow the compilation of a class with a `@Injectable()` decorator without parameters
10434
+ const meta = srcMeta || { providedIn: null };
10435
+ const compilerMeta = {
10436
+ name: type.name,
10437
+ type: type,
10438
+ typeArgumentCount: 0,
10439
+ providedIn: meta.providedIn,
10440
+ };
10441
+ if ((isUseClassProvider(meta) || isUseFactoryProvider(meta)) && meta.deps !== undefined) {
10442
+ compilerMeta.deps = convertDependencies(meta.deps);
10443
+ }
10444
+ // Check to see if the user explicitly provided a `useXxxx` property.
10445
+ if (isUseClassProvider(meta)) {
10446
+ compilerMeta.useClass = meta.useClass;
10447
+ }
10448
+ else if (isUseValueProvider(meta)) {
10449
+ compilerMeta.useValue = meta.useValue;
10450
+ }
10451
+ else if (isUseFactoryProvider(meta)) {
10452
+ compilerMeta.useFactory = meta.useFactory;
10453
+ }
10454
+ else if (isUseExistingProvider(meta)) {
10455
+ compilerMeta.useExisting = meta.useExisting;
10456
+ }
10457
+ return compilerMeta;
10458
+ }
10459
+
10460
+ /**
10461
+ * Injectable decorator and metadata.
10462
+ *
10463
+ * @Annotation
10464
+ * @publicApi
10465
+ */
10466
+ const Injectable = makeDecorator('Injectable', undefined, undefined, undefined, (type, meta) => compileInjectable(type, meta));
10467
+
10468
+ /**
10469
+ * Create a new `Injector` which is configured using a `defType` of `InjectorType<any>`s.
10470
+ */
10471
+ function createInjector(defType, parent = null, additionalProviders = null, name) {
10472
+ const injector = createInjectorWithoutInjectorInstances(defType, parent, additionalProviders, name);
10473
+ injector.resolveInjectorInitializers();
10474
+ return injector;
10475
+ }
10476
+ /**
10477
+ * Creates a new injector without eagerly resolving its injector types. Can be used in places
10478
+ * where resolving the injector types immediately can lead to an infinite loop. The injector types
10479
+ * should be resolved at a later point by calling `_resolveInjectorDefTypes`.
10480
+ */
10481
+ function createInjectorWithoutInjectorInstances(defType, parent = null, additionalProviders = null, name, scopes = new Set()) {
10482
+ const providers = [
10483
+ additionalProviders || EMPTY_ARRAY,
10484
+ importProvidersFrom(defType),
10485
+ ];
10486
+ name = name || (typeof defType === 'object' ? undefined : stringify(defType));
10487
+ return new R3Injector(providers, parent || getNullInjector(), name || null, scopes);
10488
+ }
10489
+
10490
+ /**
10491
+ * Concrete injectors implement this interface. Injectors are configured
10492
+ * with [providers](guide/glossary#provider) that associate
10493
+ * dependencies of various types with [injection tokens](guide/glossary#di-token).
10494
+ *
10495
+ * @see ["DI Providers"](guide/dependency-injection-providers).
10496
+ * @see {@link StaticProvider}
10497
+ *
10498
+ * @usageNotes
10499
+ *
10500
+ * The following example creates a service injector instance.
10501
+ *
10502
+ * {@example core/di/ts/provider_spec.ts region='ConstructorProvider'}
10503
+ *
10504
+ * ### Usage example
10505
+ *
10506
+ * {@example core/di/ts/injector_spec.ts region='Injector'}
10507
+ *
10508
+ * `Injector` returns itself when given `Injector` as a token:
10509
+ *
10510
+ * {@example core/di/ts/injector_spec.ts region='injectInjector'}
10511
+ *
10512
+ * @publicApi
10513
+ */
10514
+ class Injector {
10515
+ static { this.THROW_IF_NOT_FOUND = THROW_IF_NOT_FOUND; }
10516
+ static { this.NULL = ( /* @__PURE__ */new NullInjector()); }
10517
+ static create(options, parent) {
10518
+ if (Array.isArray(options)) {
10519
+ return createInjector({ name: '' }, parent, options, '');
10520
+ }
10521
+ else {
10522
+ const name = options.name ?? '';
10523
+ return createInjector({ name }, options.parent, options.providers, name);
10524
+ }
10525
+ }
10526
+ /** @nocollapse */
10527
+ static { this.ɵprov = ɵɵdefineInjectable({
10528
+ token: Injector,
10529
+ providedIn: 'any',
10530
+ factory: () => ɵɵinject(INJECTOR),
10531
+ }); }
10532
+ /**
10533
+ * @internal
10534
+ * @nocollapse
10535
+ */
10536
+ static { this.__NG_ELEMENT_ID__ = -1 /* InjectorMarkers.Injector */; }
10537
+ }
10538
+
10539
+ /**
10540
+ * @module
10541
+ * @description
10542
+ * The `di` module provides dependency injection container services.
10543
+ */
10544
+
10545
+ /**
10546
+ * This file should not be necessary because node resolution should just default to `./di/index`!
10547
+ *
10548
+ * However it does not seem to work and it breaks:
10549
+ * - //packages/animations/browser/test:test_web_chromium-local
10550
+ * - //packages/compiler-cli/test:extract_i18n
10551
+ * - //packages/compiler-cli/test:ngc
10552
+ * - //packages/compiler-cli/test:perform_watch
10553
+ * - //packages/compiler-cli/test/diagnostics:check_types
10554
+ * - //packages/compiler-cli/test/transformers:test
10555
+ * - //packages/compiler/test:test
10556
+ * - //tools/public_api_guard:core_api
10557
+ *
10558
+ * Remove this file once the above is solved or wait until `ngc` is deleted and then it should be
10559
+ * safe to delete this file.
10560
+ */
10561
+
10562
+ /**
10563
+ * `DestroyRef` lets you set callbacks to run for any cleanup or destruction behavior.
10564
+ * The scope of this destruction depends on where `DestroyRef` is injected. If `DestroyRef`
10565
+ * is injected in a component or directive, the callbacks run when that component or
10566
+ * directive is destroyed. Otherwise the callbacks run when a corresponding injector is destroyed.
10567
+ *
10568
+ * @publicApi
10569
+ */
10570
+ class DestroyRef {
10571
+ /**
10572
+ * @internal
10573
+ * @nocollapse
10574
+ */
10575
+ static { this.__NG_ELEMENT_ID__ = injectDestroyRef; }
10576
+ /**
10577
+ * @internal
10578
+ * @nocollapse
10579
+ */
10580
+ static { this.__NG_ENV_ID__ = (injector) => injector; }
10581
+ }
10582
+ class NodeInjectorDestroyRef extends DestroyRef {
10583
+ constructor(_lView) {
10584
+ super();
10585
+ this._lView = _lView;
10586
+ }
10587
+ onDestroy(callback) {
10588
+ storeLViewOnDestroy(this._lView, callback);
10589
+ return () => removeLViewOnDestroy(this._lView, callback);
10590
+ }
10591
+ }
10592
+ function injectDestroyRef() {
10593
+ return new NodeInjectorDestroyRef(getLView());
10594
+ }
10595
+
10596
+ /**
10597
+ *
10598
+ * @codeGenApi
10599
+ */
10600
+ function ɵɵresolveWindow(element) {
10601
+ return element.ownerDocument.defaultView;
10602
+ }
10603
+ /**
10604
+ *
10605
+ * @codeGenApi
10606
+ */
10607
+ function ɵɵresolveDocument(element) {
10608
+ return element.ownerDocument;
10609
+ }
10610
+ /**
10611
+ *
10612
+ * @codeGenApi
10613
+ */
10614
+ function ɵɵresolveBody(element) {
10615
+ return element.ownerDocument.body;
10616
+ }
10617
+ /**
10618
+ * The special delimiter we use to separate property names, prefixes, and suffixes
10619
+ * in property binding metadata. See storeBindingMetadata().
10620
+ *
10621
+ * We intentionally use the Unicode "REPLACEMENT CHARACTER" (U+FFFD) as a delimiter
10622
+ * because it is a very uncommon character that is unlikely to be part of a user's
10623
+ * property names or interpolation strings. If it is in fact used in a property
10624
+ * binding, DebugElement.properties will not return the correct value for that
10625
+ * binding. However, there should be no runtime effect for real applications.
10626
+ *
10627
+ * This character is typically rendered as a question mark inside of a diamond.
10628
+ * See https://en.wikipedia.org/wiki/Specials_(Unicode_block)
10629
+ *
10630
+ */
10631
+ const INTERPOLATION_DELIMITER = `�`;
10632
+ /**
10633
+ * Unwrap a value which might be behind a closure (for forward declaration reasons).
10634
+ */
10635
+ function maybeUnwrapFn(value) {
10277
10636
  if (value instanceof Function) {
10278
10637
  return value();
10279
10638
  }
10280
- else {
10281
- return value;
10639
+ else {
10640
+ return value;
10641
+ }
10642
+ }
10643
+ /**
10644
+ * Detects whether the code is invoked in a browser.
10645
+ * Later on, this check should be replaced with a tree-shakable
10646
+ * flag (e.g. `!isServer`).
10647
+ */
10648
+ function isPlatformBrowser(injector) {
10649
+ return (injector ?? inject(Injector)).get(PLATFORM_ID) === 'browser';
10650
+ }
10651
+
10652
+ /**
10653
+ * Register a callback to be invoked each time the application
10654
+ * finishes rendering.
10655
+ *
10656
+ * Note that the callback will run
10657
+ * - in the order it was registered
10658
+ * - once per render
10659
+ * - on browser platforms only
10660
+ *
10661
+ * <div class="alert is-important">
10662
+ *
10663
+ * Components are not guaranteed to be [hydrated](guide/hydration) before the callback runs.
10664
+ * You must use caution when directly reading or writing the DOM and layout.
10665
+ *
10666
+ * </div>
10667
+ *
10668
+ * @param callback A callback function to register
10669
+ *
10670
+ * @usageNotes
10671
+ *
10672
+ * Use `afterRender` to read or write the DOM after each render.
10673
+ *
10674
+ * ### Example
10675
+ * ```ts
10676
+ * @Component({
10677
+ * selector: 'my-cmp',
10678
+ * template: `<span #content>{{ ... }}</span>`,
10679
+ * })
10680
+ * export class MyComponent {
10681
+ * @ViewChild('content') contentRef: ElementRef;
10682
+ *
10683
+ * constructor() {
10684
+ * afterRender(() => {
10685
+ * console.log('content height: ' + this.contentRef.nativeElement.scrollHeight);
10686
+ * });
10687
+ * }
10688
+ * }
10689
+ * ```
10690
+ *
10691
+ * @developerPreview
10692
+ */
10693
+ function afterRender(callback, options) {
10694
+ !options && assertInInjectionContext(afterRender);
10695
+ const injector = options?.injector ?? inject(Injector);
10696
+ if (!isPlatformBrowser(injector)) {
10697
+ return { destroy() { } };
10698
+ }
10699
+ let destroy;
10700
+ const unregisterFn = injector.get(DestroyRef).onDestroy(() => destroy?.());
10701
+ const manager = injector.get(AfterRenderEventManager);
10702
+ const instance = new AfterRenderCallback(callback);
10703
+ destroy = () => {
10704
+ manager.unregister(instance);
10705
+ unregisterFn();
10706
+ };
10707
+ manager.register(instance);
10708
+ return { destroy };
10709
+ }
10710
+ /**
10711
+ * Register a callback to be invoked the next time the application
10712
+ * finishes rendering.
10713
+ *
10714
+ * Note that the callback will run
10715
+ * - in the order it was registered
10716
+ * - on browser platforms only
10717
+ *
10718
+ * <div class="alert is-important">
10719
+ *
10720
+ * Components are not guaranteed to be [hydrated](guide/hydration) before the callback runs.
10721
+ * You must use caution when directly reading or writing the DOM and layout.
10722
+ *
10723
+ * </div>
10724
+ *
10725
+ * @param callback A callback function to register
10726
+ *
10727
+ * @usageNotes
10728
+ *
10729
+ * Use `afterNextRender` to read or write the DOM once,
10730
+ * for example to initialize a non-Angular library.
10731
+ *
10732
+ * ### Example
10733
+ * ```ts
10734
+ * @Component({
10735
+ * selector: 'my-chart-cmp',
10736
+ * template: `<div #chart>{{ ... }}</div>`,
10737
+ * })
10738
+ * export class MyChartCmp {
10739
+ * @ViewChild('chart') chartRef: ElementRef;
10740
+ * chart: MyChart|null;
10741
+ *
10742
+ * constructor() {
10743
+ * afterNextRender(() => {
10744
+ * this.chart = new MyChart(this.chartRef.nativeElement);
10745
+ * });
10746
+ * }
10747
+ * }
10748
+ * ```
10749
+ *
10750
+ * @developerPreview
10751
+ */
10752
+ function afterNextRender(callback, options) {
10753
+ !options && assertInInjectionContext(afterNextRender);
10754
+ const injector = options?.injector ?? inject(Injector);
10755
+ if (!isPlatformBrowser(injector)) {
10756
+ return { destroy() { } };
10757
+ }
10758
+ let destroy;
10759
+ const unregisterFn = injector.get(DestroyRef).onDestroy(() => destroy?.());
10760
+ const manager = injector.get(AfterRenderEventManager);
10761
+ const instance = new AfterRenderCallback(() => {
10762
+ destroy?.();
10763
+ callback();
10764
+ });
10765
+ destroy = () => {
10766
+ manager.unregister(instance);
10767
+ unregisterFn();
10768
+ };
10769
+ manager.register(instance);
10770
+ return { destroy };
10771
+ }
10772
+ /**
10773
+ * A wrapper around a function to be used as an after render callback.
10774
+ * @private
10775
+ */
10776
+ class AfterRenderCallback {
10777
+ constructor(callback) {
10778
+ this.callback = callback;
10779
+ }
10780
+ invoke() {
10781
+ this.callback();
10782
+ }
10783
+ }
10784
+ /**
10785
+ * Implements `afterRender` and `afterNextRender` callback manager logic.
10786
+ */
10787
+ class AfterRenderEventManager {
10788
+ constructor() {
10789
+ this.callbacks = new Set();
10790
+ this.deferredCallbacks = new Set();
10791
+ this.renderDepth = 0;
10792
+ this.runningCallbacks = false;
10793
+ }
10794
+ /**
10795
+ * Mark the beginning of a render operation (i.e. CD cycle).
10796
+ * Throws if called from an `afterRender` callback.
10797
+ */
10798
+ begin() {
10799
+ if (this.runningCallbacks) {
10800
+ throw new RuntimeError(102 /* RuntimeErrorCode.RECURSIVE_APPLICATION_RENDER */, ngDevMode &&
10801
+ 'A new render operation began before the previous operation ended. ' +
10802
+ 'Did you trigger change detection from afterRender or afterNextRender?');
10803
+ }
10804
+ this.renderDepth++;
10805
+ }
10806
+ /**
10807
+ * Mark the end of a render operation. Registered callbacks
10808
+ * are invoked if there are no more pending operations.
10809
+ */
10810
+ end() {
10811
+ this.renderDepth--;
10812
+ if (this.renderDepth === 0) {
10813
+ try {
10814
+ this.runningCallbacks = true;
10815
+ for (const callback of this.callbacks) {
10816
+ callback.invoke();
10817
+ }
10818
+ }
10819
+ finally {
10820
+ this.runningCallbacks = false;
10821
+ for (const callback of this.deferredCallbacks) {
10822
+ this.callbacks.add(callback);
10823
+ }
10824
+ this.deferredCallbacks.clear();
10825
+ }
10826
+ }
10827
+ }
10828
+ register(callback) {
10829
+ // If we're currently running callbacks, new callbacks should be deferred
10830
+ // until the next render operation.
10831
+ const target = this.runningCallbacks ? this.deferredCallbacks : this.callbacks;
10832
+ target.add(callback);
10833
+ }
10834
+ unregister(callback) {
10835
+ this.callbacks.delete(callback);
10836
+ this.deferredCallbacks.delete(callback);
10837
+ }
10838
+ ngOnDestroy() {
10839
+ this.callbacks.clear();
10840
+ this.deferredCallbacks.clear();
10841
+ }
10842
+ /** @nocollapse */
10843
+ static { this.ɵprov = ɵɵdefineInjectable({
10844
+ token: AfterRenderEventManager,
10845
+ providedIn: 'root',
10846
+ factory: () => new AfterRenderEventManager(),
10847
+ }); }
10848
+ }
10849
+
10850
+ /**
10851
+ * Marks current view and all ancestors dirty.
10852
+ *
10853
+ * Returns the root view because it is found as a byproduct of marking the view tree
10854
+ * dirty, and can be used by methods that consume markViewDirty() to easily schedule
10855
+ * change detection. Otherwise, such methods would need to traverse up the view tree
10856
+ * an additional time to get the root view and schedule a tick on it.
10857
+ *
10858
+ * @param lView The starting LView to mark dirty
10859
+ * @returns the root LView
10860
+ */
10861
+ function markViewDirty(lView) {
10862
+ while (lView) {
10863
+ lView[FLAGS] |= 64 /* LViewFlags.Dirty */;
10864
+ const parent = getLViewParent(lView);
10865
+ // Stop traversing up as soon as you find a root view that wasn't attached to any container
10866
+ if (isRootView(lView) && !parent) {
10867
+ return lView;
10868
+ }
10869
+ // continue otherwise
10870
+ lView = parent;
10871
+ }
10872
+ return null;
10873
+ }
10874
+
10875
+ const ERROR_ORIGINAL_ERROR = 'ngOriginalError';
10876
+ function wrappedError(message, originalError) {
10877
+ const msg = `${message} caused by: ${originalError instanceof Error ? originalError.message : originalError}`;
10878
+ const error = Error(msg);
10879
+ error[ERROR_ORIGINAL_ERROR] = originalError;
10880
+ return error;
10881
+ }
10882
+ function getOriginalError(error) {
10883
+ return error[ERROR_ORIGINAL_ERROR];
10884
+ }
10885
+
10886
+ /**
10887
+ * Provides a hook for centralized exception handling.
10888
+ *
10889
+ * The default implementation of `ErrorHandler` prints error messages to the `console`. To
10890
+ * intercept error handling, write a custom exception handler that replaces this default as
10891
+ * appropriate for your app.
10892
+ *
10893
+ * @usageNotes
10894
+ * ### Example
10895
+ *
10896
+ * ```
10897
+ * class MyErrorHandler implements ErrorHandler {
10898
+ * handleError(error) {
10899
+ * // do something with the exception
10900
+ * }
10901
+ * }
10902
+ *
10903
+ * @NgModule({
10904
+ * providers: [{provide: ErrorHandler, useClass: MyErrorHandler}]
10905
+ * })
10906
+ * class MyModule {}
10907
+ * ```
10908
+ *
10909
+ * @publicApi
10910
+ */
10911
+ class ErrorHandler {
10912
+ constructor() {
10913
+ /**
10914
+ * @internal
10915
+ */
10916
+ this._console = console;
10917
+ }
10918
+ handleError(error) {
10919
+ const originalError = this._findOriginalError(error);
10920
+ this._console.error('ERROR', error);
10921
+ if (originalError) {
10922
+ this._console.error('ORIGINAL ERROR', originalError);
10923
+ }
10924
+ }
10925
+ /** @internal */
10926
+ _findOriginalError(error) {
10927
+ let e = error && getOriginalError(error);
10928
+ while (e && getOriginalError(e)) {
10929
+ e = getOriginalError(e);
10930
+ }
10931
+ return e || null;
10932
+ }
10933
+ }
10934
+
10935
+ /**
10936
+ * Internal token that specifies whether DOM reuse logic
10937
+ * during hydration is enabled.
10938
+ */
10939
+ const IS_HYDRATION_DOM_REUSE_ENABLED = new InjectionToken((typeof ngDevMode === 'undefined' || !!ngDevMode) ? 'IS_HYDRATION_DOM_REUSE_ENABLED' : '');
10940
+ // By default (in client rendering mode), we remove all the contents
10941
+ // of the host element and render an application after that.
10942
+ const PRESERVE_HOST_CONTENT_DEFAULT = false;
10943
+ /**
10944
+ * Internal token that indicates whether host element content should be
10945
+ * retained during the bootstrap.
10946
+ */
10947
+ const PRESERVE_HOST_CONTENT = new InjectionToken((typeof ngDevMode === 'undefined' || !!ngDevMode) ? 'PRESERVE_HOST_CONTENT' : '', {
10948
+ providedIn: 'root',
10949
+ factory: () => PRESERVE_HOST_CONTENT_DEFAULT,
10950
+ });
10951
+
10952
+ function normalizeDebugBindingName(name) {
10953
+ // Attribute names with `$` (eg `x-y$`) are valid per spec, but unsupported by some browsers
10954
+ name = camelCaseToDashCase(name.replace(/[$@]/g, '_'));
10955
+ return `ng-reflect-${name}`;
10956
+ }
10957
+ const CAMEL_CASE_REGEXP = /([A-Z])/g;
10958
+ function camelCaseToDashCase(input) {
10959
+ return input.replace(CAMEL_CASE_REGEXP, (...m) => '-' + m[1].toLowerCase());
10960
+ }
10961
+ function normalizeDebugBindingValue(value) {
10962
+ try {
10963
+ // Limit the size of the value as otherwise the DOM just gets polluted.
10964
+ return value != null ? value.toString().slice(0, 30) : value;
10965
+ }
10966
+ catch (e) {
10967
+ return '[ERROR] Exception while trying to serialize the value';
10282
10968
  }
10283
10969
  }
10284
10970
 
@@ -10381,384 +11067,140 @@ function getExpressionChangedErrorDetails(lView, bindingIndex, oldValue, newValu
10381
11067
  // first interpolation delimiter separates property name from interpolation parts (in case of
10382
11068
  // property interpolations), so we subtract one from total number of found delimiters
10383
11069
  if (matches && (matches.length - 1) > bindingIndex - idx) {
10384
- return constructDetailsForInterpolation(lView, idx, bindingIndex, meta, newValue);
10385
- }
10386
- }
10387
- }
10388
- return { propName: undefined, oldValue, newValue };
10389
- }
10390
-
10391
- class ReactiveLViewConsumer extends ReactiveNode {
10392
- constructor() {
10393
- super(...arguments);
10394
- this.consumerAllowSignalWrites = false;
10395
- this._lView = null;
10396
- }
10397
- set lView(lView) {
10398
- (typeof ngDevMode === 'undefined' || ngDevMode) &&
10399
- assertEqual(this._lView, null, 'Consumer already associated with a view.');
10400
- this._lView = lView;
10401
- }
10402
- onConsumerDependencyMayHaveChanged() {
10403
- (typeof ngDevMode === 'undefined' || ngDevMode) &&
10404
- assertDefined(this._lView, 'Updating a signal during template or host binding execution is not allowed.');
10405
- markViewDirty(this._lView);
10406
- }
10407
- onProducerUpdateValueVersion() {
10408
- // This type doesn't implement the producer side of a `ReactiveNode`.
10409
- }
10410
- get hasReadASignal() {
10411
- return this.hasProducers;
10412
- }
10413
- runInContext(fn, rf, ctx) {
10414
- const prevConsumer = setActiveConsumer(this);
10415
- this.trackingVersion++;
10416
- try {
10417
- fn(rf, ctx);
10418
- }
10419
- finally {
10420
- setActiveConsumer(prevConsumer);
10421
- }
10422
- }
10423
- destroy() {
10424
- // Incrementing the version means that every producer which tries to update this consumer will
10425
- // consider its record stale, and not notify.
10426
- this.trackingVersion++;
10427
- }
10428
- }
10429
- let currentConsumer = null;
10430
- function getOrCreateCurrentLViewConsumer() {
10431
- currentConsumer ??= new ReactiveLViewConsumer();
10432
- return currentConsumer;
10433
- }
10434
- /**
10435
- * Create a new template consumer pointing at the specified LView.
10436
- * Sometimes, a previously created consumer may be reused, in order to save on allocations. In that
10437
- * case, the LView will be updated.
10438
- */
10439
- function getReactiveLViewConsumer(lView, slot) {
10440
- return lView[slot] ?? getOrCreateCurrentLViewConsumer();
10441
- }
10442
- /**
10443
- * Assigns the `currentTemplateContext` to its LView's `REACTIVE_CONSUMER` slot if there are tracked
10444
- * producers.
10445
- *
10446
- * The presence of producers means that a signal was read while the consumer was the active
10447
- * consumer.
10448
- *
10449
- * If no producers are present, we do not assign the current template context. This also means we
10450
- * can just reuse the template context for the next LView.
10451
- */
10452
- function commitLViewConsumerIfHasProducers(lView, slot) {
10453
- const consumer = getOrCreateCurrentLViewConsumer();
10454
- if (!consumer.hasReadASignal) {
10455
- return;
10456
- }
10457
- lView[slot] = currentConsumer;
10458
- consumer.lView = lView;
10459
- currentConsumer = new ReactiveLViewConsumer();
10460
- }
10461
-
10462
- /** A special value which designates that a value has not changed. */
10463
- const NO_CHANGE = (typeof ngDevMode === 'undefined' || ngDevMode) ? { __brand__: 'NO_CHANGE' } : {};
10464
-
10465
- /**
10466
- * Advances to an element for later binding instructions.
10467
- *
10468
- * Used in conjunction with instructions like {@link property} to act on elements with specified
10469
- * indices, for example those created with {@link element} or {@link elementStart}.
10470
- *
10471
- * ```ts
10472
- * (rf: RenderFlags, ctx: any) => {
10473
- * if (rf & 1) {
10474
- * text(0, 'Hello');
10475
- * text(1, 'Goodbye')
10476
- * element(2, 'div');
10477
- * }
10478
- * if (rf & 2) {
10479
- * advance(2); // Advance twice to the <div>.
10480
- * property('title', 'test');
10481
- * }
10482
- * }
10483
- * ```
10484
- * @param delta Number of elements to advance forwards by.
10485
- *
10486
- * @codeGenApi
10487
- */
10488
- function ɵɵadvance(delta) {
10489
- ngDevMode && assertGreaterThan(delta, 0, 'Can only advance forward');
10490
- selectIndexInternal(getTView(), getLView(), getSelectedIndex() + delta, !!ngDevMode && isInCheckNoChangesMode());
10491
- }
10492
- function selectIndexInternal(tView, lView, index, checkNoChangesMode) {
10493
- ngDevMode && assertIndexInDeclRange(lView, index);
10494
- // Flush the initial hooks for elements in the view that have been added up to this point.
10495
- // PERF WARNING: do NOT extract this to a separate function without running benchmarks
10496
- if (!checkNoChangesMode) {
10497
- const hooksInitPhaseCompleted = (lView[FLAGS] & 3 /* LViewFlags.InitPhaseStateMask */) === 3 /* InitPhaseState.InitPhaseCompleted */;
10498
- if (hooksInitPhaseCompleted) {
10499
- const preOrderCheckHooks = tView.preOrderCheckHooks;
10500
- if (preOrderCheckHooks !== null) {
10501
- executeCheckHooks(lView, preOrderCheckHooks, index);
10502
- }
10503
- }
10504
- else {
10505
- const preOrderHooks = tView.preOrderHooks;
10506
- if (preOrderHooks !== null) {
10507
- executeInitAndCheckHooks(lView, preOrderHooks, 0 /* InitPhaseState.OnInitHooksToBeRun */, index);
10508
- }
10509
- }
10510
- }
10511
- // We must set the selected index *after* running the hooks, because hooks may have side-effects
10512
- // that cause other template functions to run, thus updating the selected index, which is global
10513
- // 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;
11070
+ return constructDetailsForInterpolation(lView, idx, bindingIndex, meta, newValue);
11071
+ }
11072
+ }
11073
+ }
11074
+ return { propName: undefined, oldValue, newValue };
10629
11075
  }
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);
11076
+
11077
+ class ReactiveLViewConsumer extends ReactiveNode {
11078
+ constructor() {
11079
+ super(...arguments);
11080
+ this.consumerAllowSignalWrites = false;
11081
+ this._lView = null;
10641
11082
  }
10642
- // Check to see if the user explicitly provided a `useXxxx` property.
10643
- if (isUseClassProvider(meta)) {
10644
- compilerMeta.useClass = meta.useClass;
11083
+ set lView(lView) {
11084
+ (typeof ngDevMode === 'undefined' || ngDevMode) &&
11085
+ assertEqual(this._lView, null, 'Consumer already associated with a view.');
11086
+ this._lView = lView;
10645
11087
  }
10646
- else if (isUseValueProvider(meta)) {
10647
- compilerMeta.useValue = meta.useValue;
11088
+ onConsumerDependencyMayHaveChanged() {
11089
+ (typeof ngDevMode === 'undefined' || ngDevMode) &&
11090
+ assertDefined(this._lView, 'Updating a signal during template or host binding execution is not allowed.');
11091
+ markViewDirty(this._lView);
10648
11092
  }
10649
- else if (isUseFactoryProvider(meta)) {
10650
- compilerMeta.useFactory = meta.useFactory;
11093
+ onProducerUpdateValueVersion() {
11094
+ // This type doesn't implement the producer side of a `ReactiveNode`.
10651
11095
  }
10652
- else if (isUseExistingProvider(meta)) {
10653
- compilerMeta.useExisting = meta.useExisting;
11096
+ get hasReadASignal() {
11097
+ return this.hasProducers;
11098
+ }
11099
+ runInContext(fn, rf, ctx) {
11100
+ const prevConsumer = setActiveConsumer(this);
11101
+ this.trackingVersion++;
11102
+ try {
11103
+ fn(rf, ctx);
11104
+ }
11105
+ finally {
11106
+ setActiveConsumer(prevConsumer);
11107
+ }
11108
+ }
11109
+ destroy() {
11110
+ // Incrementing the version means that every producer which tries to update this consumer will
11111
+ // consider its record stale, and not notify.
11112
+ this.trackingVersion++;
10654
11113
  }
10655
- return compilerMeta;
10656
11114
  }
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
-
11115
+ let currentConsumer = null;
11116
+ function getOrCreateCurrentLViewConsumer() {
11117
+ currentConsumer ??= new ReactiveLViewConsumer();
11118
+ return currentConsumer;
11119
+ }
10666
11120
  /**
10667
- * Create a new `Injector` which is configured using a `defType` of `InjectorType<any>`s.
10668
- *
10669
- * @publicApi
11121
+ * Create a new template consumer pointing at the specified LView.
11122
+ * Sometimes, a previously created consumer may be reused, in order to save on allocations. In that
11123
+ * case, the LView will be updated.
10670
11124
  */
10671
- function createInjector(defType, parent = null, additionalProviders = null, name) {
10672
- const injector = createInjectorWithoutInjectorInstances(defType, parent, additionalProviders, name);
10673
- injector.resolveInjectorInitializers();
10674
- return injector;
11125
+ function getReactiveLViewConsumer(lView, slot) {
11126
+ return lView[slot] ?? getOrCreateCurrentLViewConsumer();
10675
11127
  }
10676
11128
  /**
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`.
11129
+ * Assigns the `currentTemplateContext` to its LView's `REACTIVE_CONSUMER` slot if there are tracked
11130
+ * producers.
11131
+ *
11132
+ * The presence of producers means that a signal was read while the consumer was the active
11133
+ * consumer.
11134
+ *
11135
+ * If no producers are present, we do not assign the current template context. This also means we
11136
+ * can just reuse the template context for the next LView.
10680
11137
  */
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);
11138
+ function commitLViewConsumerIfHasProducers(lView, slot) {
11139
+ const consumer = getOrCreateCurrentLViewConsumer();
11140
+ if (!consumer.hasReadASignal) {
11141
+ return;
11142
+ }
11143
+ lView[slot] = currentConsumer;
11144
+ consumer.lView = lView;
11145
+ currentConsumer = new ReactiveLViewConsumer();
10688
11146
  }
10689
11147
 
11148
+ /** A special value which designates that a value has not changed. */
11149
+ const NO_CHANGE = (typeof ngDevMode === 'undefined' || ngDevMode) ? { __brand__: 'NO_CHANGE' } : {};
11150
+
10690
11151
  /**
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'}
11152
+ * Advances to an element for later binding instructions.
10707
11153
  *
10708
- * `Injector` returns itself when given `Injector` as a token:
11154
+ * Used in conjunction with instructions like {@link property} to act on elements with specified
11155
+ * indices, for example those created with {@link element} or {@link elementStart}.
10709
11156
  *
10710
- * {@example core/di/ts/injector_spec.ts region='injectInjector'}
11157
+ * ```ts
11158
+ * (rf: RenderFlags, ctx: any) => {
11159
+ * if (rf & 1) {
11160
+ * text(0, 'Hello');
11161
+ * text(1, 'Goodbye')
11162
+ * element(2, 'div');
11163
+ * }
11164
+ * if (rf & 2) {
11165
+ * advance(2); // Advance twice to the <div>.
11166
+ * property('title', 'test');
11167
+ * }
11168
+ * }
11169
+ * ```
11170
+ * @param delta Number of elements to advance forwards by.
10711
11171
  *
10712
- * @publicApi
11172
+ * @codeGenApi
10713
11173
  */
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, '');
11174
+ function ɵɵadvance(delta) {
11175
+ ngDevMode && assertGreaterThan(delta, 0, 'Can only advance forward');
11176
+ selectIndexInternal(getTView(), getLView(), getSelectedIndex() + delta, !!ngDevMode && isInCheckNoChangesMode());
11177
+ }
11178
+ function selectIndexInternal(tView, lView, index, checkNoChangesMode) {
11179
+ ngDevMode && assertIndexInDeclRange(lView, index);
11180
+ // Flush the initial hooks for elements in the view that have been added up to this point.
11181
+ // PERF WARNING: do NOT extract this to a separate function without running benchmarks
11182
+ if (!checkNoChangesMode) {
11183
+ const hooksInitPhaseCompleted = (lView[FLAGS] & 3 /* LViewFlags.InitPhaseStateMask */) === 3 /* InitPhaseState.InitPhaseCompleted */;
11184
+ if (hooksInitPhaseCompleted) {
11185
+ const preOrderCheckHooks = tView.preOrderCheckHooks;
11186
+ if (preOrderCheckHooks !== null) {
11187
+ executeCheckHooks(lView, preOrderCheckHooks, index);
11188
+ }
10720
11189
  }
10721
11190
  else {
10722
- const name = options.name ?? '';
10723
- return createInjector({ name }, options.parent, options.providers, name);
11191
+ const preOrderHooks = tView.preOrderHooks;
11192
+ if (preOrderHooks !== null) {
11193
+ executeInitAndCheckHooks(lView, preOrderHooks, 0 /* InitPhaseState.OnInitHooksToBeRun */, index);
11194
+ }
10724
11195
  }
10725
11196
  }
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 */; }
11197
+ // We must set the selected index *after* running the hooks, because hooks may have side-effects
11198
+ // that cause other template functions to run, thus updating the selected index, which is global
11199
+ // state. If we run `setSelectedIndex` *before* we run the hooks, in some cases the selected index
11200
+ // will be altered by the time we leave the `ɵɵadvance` instruction.
11201
+ setSelectedIndex(index);
10737
11202
  }
10738
11203
 
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
- */
10761
-
10762
11204
  function ɵɵdirectiveInject(token, flags = InjectFlags.Default) {
10763
11205
  const lView = getLView();
10764
11206
  // Fall back to inject() if view hasn't been created. This situation can happen in tests
@@ -10769,7 +11211,9 @@ function ɵɵdirectiveInject(token, flags = InjectFlags.Default) {
10769
11211
  return ɵɵinject(token, flags);
10770
11212
  }
10771
11213
  const tNode = getCurrentTNode();
10772
- return getOrCreateInjectable(tNode, lView, resolveForwardRef(token), flags);
11214
+ const value = getOrCreateInjectable(tNode, lView, resolveForwardRef(token), flags);
11215
+ ngDevMode && emitInjectEvent(token, value, flags);
11216
+ return value;
10773
11217
  }
10774
11218
  /**
10775
11219
  * Throws an error indicating that a factory function could not be generated by the compiler for a
@@ -12210,40 +12654,6 @@ function renderChildComponents(hostLView, components) {
12210
12654
  }
12211
12655
  }
12212
12656
 
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
12657
  /**
12248
12658
  * Tracks all effects registered within a given application and runs them via `flush`.
12249
12659
  */
@@ -12412,13 +12822,17 @@ function collectNativeNodes(tView, lView, tNode, result, isProjection = false) {
12412
12822
  }
12413
12823
 
12414
12824
  function detectChangesInternal(tView, lView, context, notifyErrorHandler = true) {
12415
- const rendererFactory = lView[ENVIRONMENT].rendererFactory;
12825
+ const environment = lView[ENVIRONMENT];
12826
+ const rendererFactory = environment.rendererFactory;
12827
+ const afterRenderEventManager = environment.afterRenderEventManager;
12416
12828
  // Check no changes mode is a dev only mode used to verify that bindings have not changed
12417
12829
  // since they were assigned. We do not want to invoke renderer factory functions in that mode
12418
12830
  // to avoid any possible side-effects.
12419
12831
  const checkNoChangesMode = !!ngDevMode && isInCheckNoChangesMode();
12420
- if (!checkNoChangesMode && rendererFactory.begin)
12421
- rendererFactory.begin();
12832
+ if (!checkNoChangesMode) {
12833
+ rendererFactory.begin?.();
12834
+ afterRenderEventManager?.begin();
12835
+ }
12422
12836
  try {
12423
12837
  refreshView(tView, lView, tView.template, context);
12424
12838
  }
@@ -12429,11 +12843,14 @@ function detectChangesInternal(tView, lView, context, notifyErrorHandler = true)
12429
12843
  throw error;
12430
12844
  }
12431
12845
  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();
12846
+ if (!checkNoChangesMode) {
12847
+ rendererFactory.end?.();
12848
+ // One final flush of the effects queue to catch any effects created in `ngAfterViewInit` or
12849
+ // other post-order hooks.
12850
+ environment.effectManager?.flush();
12851
+ // Invoke all callbacks registered via `after*Render`, if needed.
12852
+ afterRenderEventManager?.end();
12853
+ }
12437
12854
  }
12438
12855
  }
12439
12856
  function checkNoChangesInternal(tView, lView, context, notifyErrorHandler = true) {
@@ -12915,7 +13332,7 @@ class ViewRef$1 {
12915
13332
  }
12916
13333
  detachFromAppRef() {
12917
13334
  this._appRef = null;
12918
- renderDetachView(this._lView[TVIEW], this._lView);
13335
+ detachViewFromDOM(this._lView[TVIEW], this._lView);
12919
13336
  }
12920
13337
  attachToAppRef(appRef) {
12921
13338
  if (this._attachedToViewContainer) {
@@ -13054,10 +13471,12 @@ class ComponentFactory extends ComponentFactory$1 {
13054
13471
  }
13055
13472
  const sanitizer = rootViewInjector.get(Sanitizer, null);
13056
13473
  const effectManager = rootViewInjector.get(EffectManager, null);
13474
+ const afterRenderEventManager = rootViewInjector.get(AfterRenderEventManager, null);
13057
13475
  const environment = {
13058
13476
  rendererFactory,
13059
13477
  sanitizer,
13060
13478
  effectManager,
13479
+ afterRenderEventManager,
13061
13480
  };
13062
13481
  const hostRenderer = rendererFactory.createRenderer(null, this.componentDef);
13063
13482
  // Determine a tag name used for creating host elements when this component is created
@@ -13072,9 +13491,13 @@ class ComponentFactory extends ComponentFactory$1 {
13072
13491
  const nonSignalFlags = this.componentDef.onPush ? 64 /* LViewFlags.Dirty */ | 512 /* LViewFlags.IsRoot */ :
13073
13492
  16 /* LViewFlags.CheckAlways */ | 512 /* LViewFlags.IsRoot */;
13074
13493
  const rootFlags = this.componentDef.signals ? signalFlags : nonSignalFlags;
13494
+ let hydrationInfo = null;
13495
+ if (hostRNode !== null) {
13496
+ hydrationInfo = retrieveHydrationInfo(hostRNode, rootViewInjector, true /* isRootView */);
13497
+ }
13075
13498
  // Create the root view. Uses empty TView and ContentTemplate.
13076
13499
  const rootTView = createTView(0 /* TViewType.Root */, null, null, 1, 0, null, null, null, null, null, null);
13077
- const rootLView = createLView(null, rootTView, null, rootFlags, null, null, environment, hostRenderer, rootViewInjector, null, null);
13500
+ const rootLView = createLView(null, rootTView, null, rootFlags, null, null, environment, hostRenderer, rootViewInjector, null, hydrationInfo);
13078
13501
  // rootView is the parent when bootstrapping
13079
13502
  // TODO(misko): it looks like we are entering view here but we don't really need to as
13080
13503
  // `renderView` does that. However as the code is written it is needed because
@@ -13175,12 +13598,6 @@ class ComponentRef extends ComponentRef$1 {
13175
13598
  this.hostView.onDestroy(callback);
13176
13599
  }
13177
13600
  }
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
13601
  /** Creates a TNode that can be used to instantiate a root component. */
13185
13602
  function createRootComponentTNode(lView, rNode) {
13186
13603
  const tView = lView[TVIEW];
@@ -13207,7 +13624,7 @@ function createRootComponentTNode(lView, rNode) {
13207
13624
  function createRootComponentView(tNode, hostRNode, rootComponentDef, rootDirectives, rootView, environment, hostRenderer) {
13208
13625
  const tView = rootView[TVIEW];
13209
13626
  applyRootComponentStyling(rootDirectives, tNode, hostRNode, hostRenderer);
13210
- // Hydration info is on the host element and needs to be retreived
13627
+ // Hydration info is on the host element and needs to be retrieved
13211
13628
  // and passed to the component LView.
13212
13629
  let hydrationInfo = null;
13213
13630
  if (hostRNode !== null) {
@@ -21290,6 +21707,18 @@ function ɵɵi18nPostprocess(message, replacements = {}) {
21290
21707
  return i18nPostprocess(message, replacements);
21291
21708
  }
21292
21709
 
21710
+ /**
21711
+ * Creates runtime data structures for `{#defer}` blocks.
21712
+ *
21713
+ * @param index The index of the defer block in the data array
21714
+ * @param deferredDepsFn Function that contains dependencies for this defer block
21715
+ *
21716
+ * @codeGenApi
21717
+ */
21718
+ function ɵɵdefer(index, deferredDepsFn) {
21719
+ // TODO: implement runtime logic.
21720
+ }
21721
+
21293
21722
  /*
21294
21723
  * This file re-exports all symbols contained in this directory.
21295
21724
  *
@@ -21354,9 +21783,15 @@ function resolveProvider(provider, tInjectables, lInjectablesBlueprint, isCompon
21354
21783
  else {
21355
21784
  const tView = getTView();
21356
21785
  const lView = getLView();
21357
- let token = isTypeProvider(provider) ? provider : resolveForwardRef(provider.provide);
21358
- let providerFactory = providerToFactory(provider);
21359
21786
  const tNode = getCurrentTNode();
21787
+ let token = isTypeProvider(provider) ? provider : resolveForwardRef(provider.provide);
21788
+ const providerFactory = providerToFactory(provider);
21789
+ if (ngDevMode) {
21790
+ const injector = new NodeInjector(tNode, lView);
21791
+ runInInjectorProfilerContext(injector, token, () => {
21792
+ emitProviderConfiguredEvent(provider, isViewProvider);
21793
+ });
21794
+ }
21360
21795
  const beginIndex = tNode.providerIndexes & 1048575 /* TNodeProviderIndexes.ProvidersStartIndexMask */;
21361
21796
  const endIndex = tNode.directiveStart;
21362
21797
  const cptViewProvidersCount = tNode.providerIndexes >> 20 /* TNodeProviderIndexes.CptViewProvidersCountShift */;
@@ -22576,6 +23011,13 @@ function ɵɵpipe(index, pipeName) {
22576
23011
  pipeDef = tView.data[adjustedIndex];
22577
23012
  }
22578
23013
  const pipeFactory = pipeDef.factory || (pipeDef.factory = getFactoryDef(pipeDef.type, true));
23014
+ let previousInjectorProfilerContext;
23015
+ if (ngDevMode) {
23016
+ previousInjectorProfilerContext = setInjectorProfilerContext({
23017
+ injector: new NodeInjector(getCurrentTNode(), getLView()),
23018
+ token: pipeDef.type
23019
+ });
23020
+ }
22579
23021
  const previousInjectImplementation = setInjectImplementation(ɵɵdirectiveInject);
22580
23022
  try {
22581
23023
  // DI for pipes is supposed to behave like directives when placed on a component
@@ -22590,6 +23032,7 @@ function ɵɵpipe(index, pipeName) {
22590
23032
  // we have to restore the injector implementation in finally, just in case the creation of the
22591
23033
  // pipe throws an error.
22592
23034
  setInjectImplementation(previousInjectImplementation);
23035
+ ngDevMode && setInjectorProfilerContext(previousInjectorProfilerContext);
22593
23036
  }
22594
23037
  }
22595
23038
  /**
@@ -22964,6 +23407,57 @@ class QueryList {
22964
23407
  }
22965
23408
  }
22966
23409
 
23410
+ function createAndRenderEmbeddedLView(declarationLView, templateTNode, context, options) {
23411
+ const embeddedTView = templateTNode.tView;
23412
+ ngDevMode && assertDefined(embeddedTView, 'TView must be defined for a template node.');
23413
+ ngDevMode && assertTNodeForLView(templateTNode, declarationLView);
23414
+ // Embedded views follow the change detection strategy of the view they're declared in.
23415
+ const isSignalView = declarationLView[FLAGS] & 4096 /* LViewFlags.SignalView */;
23416
+ const viewFlags = isSignalView ? 4096 /* LViewFlags.SignalView */ : 16 /* LViewFlags.CheckAlways */;
23417
+ const embeddedLView = createLView(declarationLView, embeddedTView, context, viewFlags, null, templateTNode, null, null, null, options?.injector ?? null, options?.hydrationInfo ?? null);
23418
+ const declarationLContainer = declarationLView[templateTNode.index];
23419
+ ngDevMode && assertLContainer(declarationLContainer);
23420
+ embeddedLView[DECLARATION_LCONTAINER] = declarationLContainer;
23421
+ const declarationViewLQueries = declarationLView[QUERIES];
23422
+ if (declarationViewLQueries !== null) {
23423
+ embeddedLView[QUERIES] = declarationViewLQueries.createEmbeddedView(embeddedTView);
23424
+ }
23425
+ // execute creation mode of a view
23426
+ renderView(embeddedTView, embeddedLView, context);
23427
+ return embeddedLView;
23428
+ }
23429
+ function getLViewFromLContainer(lContainer, index) {
23430
+ const adjustedIndex = CONTAINER_HEADER_OFFSET + index;
23431
+ // avoid reading past the array boundaries
23432
+ if (adjustedIndex < lContainer.length) {
23433
+ const lView = lContainer[adjustedIndex];
23434
+ ngDevMode && assertLView(lView);
23435
+ return lView;
23436
+ }
23437
+ return undefined;
23438
+ }
23439
+ function addLViewToLContainer(lContainer, lView, index, addToDOM = true) {
23440
+ const tView = lView[TVIEW];
23441
+ // insert to the view tree so the new view can be change-detected
23442
+ insertView(tView, lView, lContainer, index);
23443
+ // insert to the view to the DOM tree
23444
+ if (addToDOM) {
23445
+ const beforeNode = getBeforeNodeForView(index, lContainer);
23446
+ const renderer = lView[RENDERER];
23447
+ const parentRNode = nativeParentNode(renderer, lContainer[NATIVE]);
23448
+ if (parentRNode !== null) {
23449
+ addViewToDOM(tView, lContainer[T_HOST], renderer, lView, parentRNode, beforeNode);
23450
+ }
23451
+ }
23452
+ }
23453
+ function removeLViewFromLContainer(lContainer, index) {
23454
+ const lView = detachView(lContainer, index);
23455
+ if (lView !== undefined) {
23456
+ destroyLView(lView[TVIEW], lView);
23457
+ }
23458
+ return lView;
23459
+ }
23460
+
22967
23461
  /**
22968
23462
  * Represents an embedded template that can be used to instantiate embedded views.
22969
23463
  * To instantiate embedded views based on a template, use the `ViewContainerRef`
@@ -23009,25 +23503,13 @@ const R3TemplateRef = class TemplateRef extends ViewEngineTemplateRef {
23009
23503
  return this._declarationTContainer.tView?.ssrId || null;
23010
23504
  }
23011
23505
  createEmbeddedView(context, injector) {
23012
- return this.createEmbeddedViewImpl(context, injector, null);
23506
+ return this.createEmbeddedViewImpl(context, injector);
23013
23507
  }
23014
23508
  /**
23015
23509
  * @internal
23016
23510
  */
23017
23511
  createEmbeddedViewImpl(context, injector, hydrationInfo) {
23018
- // Embedded views follow the change detection strategy of the view they're declared in.
23019
- const isSignalView = this._declarationLView[FLAGS] & 4096 /* LViewFlags.SignalView */;
23020
- const viewFlags = isSignalView ? 4096 /* LViewFlags.SignalView */ : 16 /* LViewFlags.CheckAlways */;
23021
- const embeddedTView = this._declarationTContainer.tView;
23022
- const embeddedLView = createLView(this._declarationLView, embeddedTView, context, viewFlags, null, embeddedTView.declTNode, null, null, null, injector || null, hydrationInfo || null);
23023
- const declarationLContainer = this._declarationLView[this._declarationTContainer.index];
23024
- ngDevMode && assertLContainer(declarationLContainer);
23025
- embeddedLView[DECLARATION_LCONTAINER] = declarationLContainer;
23026
- const declarationViewLQueries = this._declarationLView[QUERIES];
23027
- if (declarationViewLQueries !== null) {
23028
- embeddedLView[QUERIES] = declarationViewLQueries.createEmbeddedView(embeddedTView);
23029
- }
23030
- renderView(embeddedTView, embeddedLView, context);
23512
+ const embeddedLView = createAndRenderEmbeddedLView(this._declarationLView, this._declarationTContainer, context, { injector, hydrationInfo });
23031
23513
  return new ViewRef$1(embeddedLView);
23032
23514
  }
23033
23515
  };
@@ -23124,11 +23606,20 @@ function cleanupLView(lView) {
23124
23606
  function cleanupDehydratedViews(appRef) {
23125
23607
  const viewRefs = appRef._views;
23126
23608
  for (const viewRef of viewRefs) {
23127
- const lView = getComponentLViewForHydration(viewRef);
23609
+ const lNode = getLNodeForHydration(viewRef);
23128
23610
  // An `lView` might be `null` if a `ViewRef` represents
23129
23611
  // an embedded view (not a component view).
23130
- if (lView !== null && lView[HOST] !== null) {
23131
- cleanupLView(lView);
23612
+ if (lNode !== null && lNode[HOST] !== null) {
23613
+ if (isLView(lNode)) {
23614
+ cleanupLView(lNode);
23615
+ }
23616
+ else {
23617
+ // Cleanup in the root component view
23618
+ const componentLView = lNode[HOST];
23619
+ cleanupLView(componentLView);
23620
+ // Cleanup in all views within this view container
23621
+ cleanupLContainer(lNode);
23622
+ }
23132
23623
  ngDevMode && ngDevMode.dehydratedViewsCleanupRuns++;
23133
23624
  }
23134
23625
  }
@@ -23305,7 +23796,7 @@ const R3ViewContainerRef = class ViewContainerRef extends VE_ViewContainerRef {
23305
23796
  let index;
23306
23797
  // This function supports 2 signatures and we need to handle options correctly for both:
23307
23798
  // 1. When first argument is a Component type. This signature also requires extra
23308
- // options to be provided as as object (more ergonomic option).
23799
+ // options to be provided as object (more ergonomic option).
23309
23800
  // 2. First argument is a Component factory. In this case extra options are represented as
23310
23801
  // positional arguments. This signature is less ergonomic and will be deprecated.
23311
23802
  if (isComponentFactory) {
@@ -23410,16 +23901,7 @@ const R3ViewContainerRef = class ViewContainerRef extends VE_ViewContainerRef {
23410
23901
  // Logical operation of adding `LView` to `LContainer`
23411
23902
  const adjustedIdx = this._adjustIndex(index);
23412
23903
  const lContainer = this._lContainer;
23413
- insertView(tView, lView, lContainer, adjustedIdx);
23414
- // Physical operation of adding the DOM nodes.
23415
- if (!skipDomInsertion) {
23416
- const beforeNode = getBeforeNodeForView(adjustedIdx, lContainer);
23417
- const renderer = lView[RENDERER];
23418
- const parentRNode = nativeParentNode(renderer, lContainer[NATIVE]);
23419
- if (parentRNode !== null) {
23420
- addViewToContainer(tView, lContainer[T_HOST], renderer, lView, parentRNode, beforeNode);
23421
- }
23422
- }
23904
+ addLViewToLContainer(lContainer, lView, adjustedIdx, !skipDomInsertion);
23423
23905
  viewRef.attachToViewContainerRef();
23424
23906
  addToArray(getOrCreateViewRefs(lContainer), adjustedIdx, viewRef);
23425
23907
  return viewRef;
@@ -24169,6 +24651,7 @@ const angularCoreEnv = (() => ({
24169
24651
  'ɵɵclassProp': ɵɵclassProp,
24170
24652
  'ɵɵadvance': ɵɵadvance,
24171
24653
  'ɵɵtemplate': ɵɵtemplate,
24654
+ 'ɵɵdefer': ɵɵdefer,
24172
24655
  'ɵɵtext': ɵɵtext,
24173
24656
  'ɵɵtextInterpolate': ɵɵtextInterpolate,
24174
24657
  'ɵɵtextInterpolate1': ɵɵtextInterpolate1,
@@ -25867,6 +26350,206 @@ const COMPILER_OPTIONS = new InjectionToken('compilerOptions');
25867
26350
  class CompilerFactory {
25868
26351
  }
25869
26352
 
26353
+ /**
26354
+ * These are the data structures that our framework injector profiler will fill with data in order
26355
+ * to support DI debugging APIs.
26356
+ *
26357
+ * resolverToTokenToDependencies: Maps an injector to a Map of tokens to an Array of
26358
+ * dependencies. Injector -> Token -> Dependencies This is used to support the
26359
+ * getDependenciesFromInjectable API, which takes in an injector and a token and returns it's
26360
+ * dependencies.
26361
+ *
26362
+ * resolverToProviders: Maps a DI resolver (an Injector or an LView) to the providers configured
26363
+ * within it This is used to support the getInjectorProviders API, which takes in an injector and
26364
+ * returns the providers that it was configured with.
26365
+ *
26366
+ * standaloneInjectorToComponent: Maps the injector of a standalone component to the standalone
26367
+ * component that it is associated with. Used in the getInjectorProviders API, specificially in the
26368
+ * discovery of import paths for each provider. This is necessary because the imports array of a
26369
+ * standalone component is processed and configured in its standalone injector, but exists within
26370
+ * the component's definition. Because getInjectorProviders takes in an injector, if that injector
26371
+ * is the injector of a standalone component, we need to be able to discover the place where the
26372
+ * imports array is located (the component) in order to flatten the imports array within it to
26373
+ * discover all of it's providers.
26374
+ *
26375
+ *
26376
+ * All of these data structures are instantiated with WeakMaps. This will ensure that the presence
26377
+ * of any object in the keys of these maps does not prevent the garbage collector from collecting
26378
+ * those objects. Because of this property of WeakMaps, these data structures will never be the
26379
+ * source of a memory leak.
26380
+ *
26381
+ * An example of this advantage: When components are destroyed, we don't need to do
26382
+ * any additional work to remove that component from our mappings.
26383
+ *
26384
+ */
26385
+ class DIDebugData {
26386
+ constructor() {
26387
+ this.resolverToTokenToDependencies = new WeakMap();
26388
+ this.resolverToProviders = new WeakMap();
26389
+ this.standaloneInjectorToComponent = new WeakMap();
26390
+ }
26391
+ reset() {
26392
+ this.resolverToTokenToDependencies =
26393
+ new WeakMap();
26394
+ this.resolverToProviders = new WeakMap();
26395
+ this.standaloneInjectorToComponent = new WeakMap();
26396
+ }
26397
+ }
26398
+ let frameworkDIDebugData = new DIDebugData();
26399
+ function getFrameworkDIDebugData() {
26400
+ return frameworkDIDebugData;
26401
+ }
26402
+ /**
26403
+ * Initalize default handling of injector events. This handling parses events
26404
+ * as they are emitted and constructs the data structures necessary to support
26405
+ * some of debug APIs.
26406
+ *
26407
+ * See handleInjectEvent, handleCreateEvent and handleProviderConfiguredEvent
26408
+ * for descriptions of each handler
26409
+ *
26410
+ * Supported APIs:
26411
+ * - getDependenciesFromInjectable
26412
+ * - getInjectorProviders
26413
+ */
26414
+ function setupFrameworkInjectorProfiler() {
26415
+ frameworkDIDebugData.reset();
26416
+ setInjectorProfiler((injectorProfilerEvent) => handleInjectorProfilerEvent(injectorProfilerEvent));
26417
+ }
26418
+ function handleInjectorProfilerEvent(injectorProfilerEvent) {
26419
+ const { context, type } = injectorProfilerEvent;
26420
+ if (type === 0 /* InjectorProfilerEventType.Inject */) {
26421
+ handleInjectEvent(context, injectorProfilerEvent.service);
26422
+ }
26423
+ else if (type === 1 /* InjectorProfilerEventType.InstanceCreatedByInjector */) {
26424
+ handleInstanceCreatedByInjectorEvent(context, injectorProfilerEvent.instance);
26425
+ }
26426
+ else if (type === 2 /* InjectorProfilerEventType.ProviderConfigured */) {
26427
+ handleProviderConfiguredEvent(context, injectorProfilerEvent.providerRecord);
26428
+ }
26429
+ }
26430
+ /**
26431
+ *
26432
+ * Stores the injected service in frameworkDIDebugData.resolverToTokenToDependencies
26433
+ * based on it's injector and token.
26434
+ *
26435
+ * @param context InjectorProfilerContext the injection context that this event occurred in.
26436
+ * @param data InjectedService the service associated with this inject event.
26437
+ *
26438
+ */
26439
+ function handleInjectEvent(context, data) {
26440
+ const diResolver = getDIResolver(context.injector);
26441
+ if (diResolver === null) {
26442
+ throwError('An Inject event must be run within an injection context.');
26443
+ }
26444
+ const diResolverToInstantiatedToken = frameworkDIDebugData.resolverToTokenToDependencies;
26445
+ if (!diResolverToInstantiatedToken.has(diResolver)) {
26446
+ diResolverToInstantiatedToken.set(diResolver, new WeakMap());
26447
+ }
26448
+ // if token is a primitive type, ignore this event. We do this because we cannot keep track of
26449
+ // non-primitive tokens in WeakMaps since they are not garbage collectable.
26450
+ if (!canBeHeldWeakly(context.token)) {
26451
+ return;
26452
+ }
26453
+ const instantiatedTokenToDependencies = diResolverToInstantiatedToken.get(diResolver);
26454
+ if (!instantiatedTokenToDependencies.has(context.token)) {
26455
+ instantiatedTokenToDependencies.set(context.token, []);
26456
+ }
26457
+ const { token, value, flags } = data;
26458
+ instantiatedTokenToDependencies.get(context.token).push({ token, value, flags });
26459
+ }
26460
+ /**
26461
+ *
26462
+ * If the created instance is an instance of a standalone component, maps the injector to that
26463
+ * standalone component in frameworkDIDebugData.standaloneInjectorToComponent
26464
+ *
26465
+ * @param context InjectorProfilerContext the injection context that this event occurred in.
26466
+ * @param data InjectorCreatedInstance an object containing the instance that was just created
26467
+ *
26468
+ */
26469
+ function handleInstanceCreatedByInjectorEvent(context, data) {
26470
+ const { value } = data;
26471
+ if (getDIResolver(context.injector) === null) {
26472
+ throwError('An InjectorCreatedInstance event must be run within an injection context.');
26473
+ }
26474
+ // if our value is an instance of a standalone component, map the injector of that standalone
26475
+ // component to the component class. Otherwise, this event is a noop.
26476
+ let standaloneComponent = undefined;
26477
+ if (typeof value === 'object') {
26478
+ standaloneComponent = value?.constructor;
26479
+ }
26480
+ if (standaloneComponent === undefined || !isStandaloneComponent(standaloneComponent)) {
26481
+ return;
26482
+ }
26483
+ const environmentInjector = context.injector.get(EnvironmentInjector, null, { optional: true });
26484
+ // Standalone components should have an environment injector. If one cannot be
26485
+ // found we may be in a test case for low level functionality that did not explictly
26486
+ // setup this injector. In those cases, we simply ignore this event.
26487
+ if (environmentInjector === null) {
26488
+ return;
26489
+ }
26490
+ const { standaloneInjectorToComponent } = frameworkDIDebugData;
26491
+ // If our injector has already been mapped, as is the case
26492
+ // when a standalone component imports another standalone component,
26493
+ // we consider the original component (the component doing the importing)
26494
+ // as the component connected to our injector.
26495
+ if (standaloneInjectorToComponent.has(environmentInjector)) {
26496
+ return;
26497
+ }
26498
+ // If our injector hasn't been mapped, then we map it to the standalone component
26499
+ standaloneInjectorToComponent.set(environmentInjector, standaloneComponent);
26500
+ }
26501
+ function isStandaloneComponent(value) {
26502
+ const def = getComponentDef(value);
26503
+ return !!def?.standalone;
26504
+ }
26505
+ /**
26506
+ *
26507
+ * Stores the emitted ProviderRecords from the InjectorProfilerEventType.ProviderConfigured
26508
+ * event in frameworkDIDebugData.resolverToProviders
26509
+ *
26510
+ * @param context InjectorProfilerContext the injection context that this event occurred in.
26511
+ * @param data ProviderRecord an object containing the instance that was just created
26512
+ *
26513
+ */
26514
+ function handleProviderConfiguredEvent(context, data) {
26515
+ const { resolverToProviders } = frameworkDIDebugData;
26516
+ const diResolver = getDIResolver(context?.injector);
26517
+ if (diResolver === null) {
26518
+ throwError('A ProviderConfigured event must be run within an injection context.');
26519
+ }
26520
+ if (!resolverToProviders.has(diResolver)) {
26521
+ resolverToProviders.set(diResolver, []);
26522
+ }
26523
+ resolverToProviders.get(diResolver).push(data);
26524
+ }
26525
+ function getDIResolver(injector) {
26526
+ let diResolver = null;
26527
+ if (injector === undefined) {
26528
+ return diResolver;
26529
+ }
26530
+ // We use the LView as the diResolver for NodeInjectors because they
26531
+ // do not persist anywhere in the framework. They are simply wrappers around an LView and a TNode
26532
+ // that do persist. Because of this, we rely on the LView of the NodeInjector in order to use
26533
+ // as a concrete key to represent this injector. If we get the same LView back later, we know
26534
+ // we're looking at the same injector.
26535
+ if (injector instanceof NodeInjector) {
26536
+ diResolver = getNodeInjectorLView(injector);
26537
+ }
26538
+ // Other injectors can be used a keys for a map because their instances
26539
+ // persist
26540
+ else {
26541
+ diResolver = injector;
26542
+ }
26543
+ return diResolver;
26544
+ }
26545
+ // inspired by
26546
+ // https://tc39.es/ecma262/multipage/executable-code-and-execution-contexts.html#sec-canbeheldweakly
26547
+ function canBeHeldWeakly(value) {
26548
+ // we check for value !== null here because typeof null === 'object
26549
+ return value !== null &&
26550
+ (typeof value === 'object' || typeof value === 'function' || typeof value === 'symbol');
26551
+ }
26552
+
25870
26553
  /**
25871
26554
  * Marks a component for check (in case of OnPush components) and synchronously
25872
26555
  * performs change detection on the application this component belongs to.
@@ -25882,6 +26565,447 @@ function applyChanges(component) {
25882
26565
  getRootComponents(component).forEach(rootComponent => detectChanges(rootComponent));
25883
26566
  }
25884
26567
 
26568
+ /**
26569
+ * Discovers the dependencies of an injectable instance. Provides DI information about each
26570
+ * dependency that the injectable was instantiated with, including where they were provided from.
26571
+ *
26572
+ * @param injector An injector instance
26573
+ * @param token a DI token that was constructed by the given injector instance
26574
+ * @returns an object that contains the created instance of token as well as all of the dependencies
26575
+ * that it was instantiated with OR undefined if the token was not created within the given
26576
+ * injector.
26577
+ */
26578
+ function getDependenciesFromInjectable(injector, token) {
26579
+ // First we check to see if the token given maps to an actual instance in the injector given.
26580
+ // We use `self: true` because we only want to look at the injector we were given.
26581
+ // We use `optional: true` because it's possible that the token we were given was never
26582
+ // constructed by the injector we were given.
26583
+ const instance = injector.get(token, null, { self: true, optional: true });
26584
+ if (instance === null) {
26585
+ throw new Error(`Unable to determine instance of ${token} in given injector`);
26586
+ }
26587
+ let diResolver = injector;
26588
+ if (injector instanceof NodeInjector) {
26589
+ diResolver = getNodeInjectorLView(injector);
26590
+ }
26591
+ const { resolverToTokenToDependencies } = getFrameworkDIDebugData();
26592
+ let dependencies = resolverToTokenToDependencies.get(diResolver)?.get?.(token) ?? [];
26593
+ const resolutionPath = getInjectorResolutionPath(injector);
26594
+ dependencies = dependencies.map(dep => {
26595
+ const flags = dep.flags;
26596
+ dep.flags = {
26597
+ optional: (8 /* InternalInjectFlags.Optional */ & flags) === 8 /* InternalInjectFlags.Optional */,
26598
+ host: (1 /* InternalInjectFlags.Host */ & flags) === 1 /* InternalInjectFlags.Host */,
26599
+ self: (2 /* InternalInjectFlags.Self */ & flags) === 2 /* InternalInjectFlags.Self */,
26600
+ skipSelf: (4 /* InternalInjectFlags.SkipSelf */ & flags) === 4 /* InternalInjectFlags.SkipSelf */,
26601
+ };
26602
+ for (let i = 0; i < resolutionPath.length; i++) {
26603
+ const injectorToCheck = resolutionPath[i];
26604
+ // if skipSelf is true we skip the first injector
26605
+ if (i === 0 && dep.flags.skipSelf) {
26606
+ continue;
26607
+ }
26608
+ // host only applies to NodeInjectors
26609
+ if (dep.flags.host && injectorToCheck instanceof EnvironmentInjector) {
26610
+ break;
26611
+ }
26612
+ const instance = injectorToCheck.get(dep.token, null, { self: true, optional: true });
26613
+ if (instance !== null) {
26614
+ // if host flag is true we double check that we can get the service from the first element
26615
+ // in the resolution path by using the host flag. This is done to make sure that we've found
26616
+ // the correct providing injector, and not a node injector that is connected to our path via
26617
+ // a router outlet.
26618
+ if (dep.flags.host) {
26619
+ const firstInjector = resolutionPath[0];
26620
+ const lookupFromFirstInjector = firstInjector.get(dep.token, null, { ...dep.flags, optional: true });
26621
+ if (lookupFromFirstInjector !== null) {
26622
+ dep.providedIn = injectorToCheck;
26623
+ }
26624
+ break;
26625
+ }
26626
+ dep.providedIn = injectorToCheck;
26627
+ break;
26628
+ }
26629
+ // if self is true we stop after the first injector
26630
+ if (i === 0 && dep.flags.self) {
26631
+ break;
26632
+ }
26633
+ }
26634
+ return dep;
26635
+ });
26636
+ return { instance, dependencies };
26637
+ }
26638
+ /**
26639
+ * Gets the class associated with an injector that contains a provider `imports` array in it's
26640
+ * definition
26641
+ *
26642
+ * For Module Injectors this returns the NgModule constructor.
26643
+ *
26644
+ * For Standalone injectors this returns the standalone component constructor.
26645
+ *
26646
+ * @param injector Injector an injector instance
26647
+ * @returns the constructor where the `imports` array that configures this injector is located
26648
+ */
26649
+ function getProviderImportsContainer(injector) {
26650
+ const { standaloneInjectorToComponent } = getFrameworkDIDebugData();
26651
+ // standalone components configure providers through a component def, so we have to
26652
+ // use the standalone component associated with this injector if Injector represents
26653
+ // a standalone components EnvironmentInjector
26654
+ if (standaloneInjectorToComponent.has(injector)) {
26655
+ return standaloneInjectorToComponent.get(injector);
26656
+ }
26657
+ // Module injectors configure providers through their NgModule def, so we use the
26658
+ // injector to lookup its NgModuleRef and through that grab its instance
26659
+ const defTypeRef = injector.get(NgModuleRef$1, null, { self: true, optional: true });
26660
+ // If we can't find an associated imports container, return null.
26661
+ // This could be the case if this function is called with an R3Injector that does not represent
26662
+ // a standalone component or NgModule.
26663
+ if (defTypeRef === null) {
26664
+ return null;
26665
+ }
26666
+ return defTypeRef.instance.constructor;
26667
+ }
26668
+ /**
26669
+ * Gets the providers configured on a NodeInjector
26670
+ *
26671
+ * @param injector A NodeInjector instance
26672
+ * @returns ProviderRecord[] an array of objects representing the providers configured on this
26673
+ * injector
26674
+ */
26675
+ function getNodeInjectorProviders(injector) {
26676
+ const diResolver = getNodeInjectorLView(injector);
26677
+ const { resolverToProviders } = getFrameworkDIDebugData();
26678
+ return resolverToProviders.get(diResolver) ?? [];
26679
+ }
26680
+ /**
26681
+ * Gets a mapping of providers configured on an injector to their import paths
26682
+ *
26683
+ * ModuleA -> imports ModuleB
26684
+ * ModuleB -> imports ModuleC
26685
+ * ModuleB -> provides MyServiceA
26686
+ * ModuleC -> provides MyServiceB
26687
+ *
26688
+ * getProviderImportPaths(ModuleA)
26689
+ * > Map(2) {
26690
+ * MyServiceA => [ModuleA, ModuleB]
26691
+ * MyServiceB => [ModuleA, ModuleB, ModuleC]
26692
+ * }
26693
+ *
26694
+ * @param providerImportsContainer constructor of class that contains an `imports` array in it's
26695
+ * definition
26696
+ * @returns A Map object that maps providers to an array of constructors representing it's import
26697
+ * path
26698
+ *
26699
+ */
26700
+ function getProviderImportPaths(providerImportsContainer) {
26701
+ const providerToPath = new Map();
26702
+ const visitedContainers = new Set();
26703
+ const visitor = walkProviderTreeToDiscoverImportPaths(providerToPath, visitedContainers);
26704
+ walkProviderTree(providerImportsContainer, visitor, [], new Set());
26705
+ return providerToPath;
26706
+ }
26707
+ /**
26708
+ *
26709
+ * Higher order function that returns a visitor for WalkProviderTree
26710
+ *
26711
+ * Takes in a Map and Set to keep track of the providers and containers
26712
+ * visited, so that we can discover the import paths of these providers
26713
+ * during the traversal.
26714
+ *
26715
+ * This visitor takes advantage of the fact that walkProviderTree performs a
26716
+ * postorder traversal of the provider tree for the passed in container. Because postorder
26717
+ * traversal recursively processes subtrees from leaf nodes until the traversal reaches the root,
26718
+ * we write a visitor that constructs provider import paths in reverse.
26719
+ *
26720
+ *
26721
+ * We use the visitedContainers set defined outside this visitor
26722
+ * because we want to run some logic only once for
26723
+ * each container in the tree. That logic can be described as:
26724
+ *
26725
+ *
26726
+ * 1. for each discovered_provider and discovered_path in the incomplete provider paths we've
26727
+ * already discovered
26728
+ * 2. get the first container in discovered_path
26729
+ * 3. if that first container is in the imports array of the container we're visiting
26730
+ * Then the container we're visiting is also in the import path of discovered_provider, so we
26731
+ * unshift discovered_path with the container we're currently visiting
26732
+ *
26733
+ *
26734
+ * Example Run:
26735
+ * ```
26736
+ * ┌──────────┐
26737
+ * │containerA│
26738
+ * ┌─imports-─┤ ├──imports─┐
26739
+ * │ │ provA │ │
26740
+ * │ │ provB │ │
26741
+ * │ └──────────┘ │
26742
+ * │ │
26743
+ * ┌▼─────────┐ ┌────────▼─┐
26744
+ * │containerB│ │containerC│
26745
+ * │ │ │ │
26746
+ * │ provD │ │ provF │
26747
+ * │ provE │ │ provG │
26748
+ * └──────────┘ └──────────┘
26749
+ * ```
26750
+ *
26751
+ * Each step of the traversal,
26752
+ *
26753
+ * ```
26754
+ * visitor(provD, containerB)
26755
+ * providerToPath === Map { provD => [containerB] }
26756
+ * visitedContainers === Set { containerB }
26757
+ *
26758
+ * visitor(provE, containerB)
26759
+ * providerToPath === Map { provD => [containerB], provE => [containerB] }
26760
+ * visitedContainers === Set { containerB }
26761
+ *
26762
+ * visitor(provF, containerC)
26763
+ * providerToPath === Map { provD => [containerB], provE => [containerB], provF => [containerC] }
26764
+ * visitedContainers === Set { containerB, containerC }
26765
+ *
26766
+ * visitor(provG, containerC)
26767
+ * providerToPath === Map {
26768
+ * provD => [containerB], provE => [containerB], provF => [containerC], provG => [containerC]
26769
+ * }
26770
+ * visitedContainers === Set { containerB, containerC }
26771
+ *
26772
+ * visitor(provA, containerA)
26773
+ * providerToPath === Map {
26774
+ * provD => [containerA, containerB],
26775
+ * provE => [containerA, containerB],
26776
+ * provF => [containerA, containerC],
26777
+ * provG => [containerA, containerC],
26778
+ * provA => [containerA]
26779
+ * }
26780
+ * visitedContainers === Set { containerB, containerC, containerA }
26781
+ *
26782
+ * visitor(provB, containerA)
26783
+ * providerToPath === Map {
26784
+ * provD => [containerA, containerB],
26785
+ * provE => [containerA, containerB],
26786
+ * provF => [containerA, containerC],
26787
+ * provG => [containerA, containerC],
26788
+ * provA => [containerA]
26789
+ * provB => [containerA]
26790
+ * }
26791
+ * visitedContainers === Set { containerB, containerC, containerA }
26792
+ * ```
26793
+ *
26794
+ * @param providerToPath Map map of providers to paths that this function fills
26795
+ * @param visitedContainers Set a set to keep track of the containers we've already visited
26796
+ * @return function(provider SingleProvider, container: Type<unknown> | InjectorType<unknown>) =>
26797
+ * void
26798
+ */
26799
+ function walkProviderTreeToDiscoverImportPaths(providerToPath, visitedContainers) {
26800
+ return (provider, container) => {
26801
+ // If the provider is not already in the providerToPath map,
26802
+ // add an entry with the provider as the key and an array containing the current container as
26803
+ // the value
26804
+ if (!providerToPath.has(provider)) {
26805
+ providerToPath.set(provider, [container]);
26806
+ }
26807
+ // This block will run exactly once for each container in the import tree.
26808
+ // This is where we run the logic to check the imports array of the current
26809
+ // container to see if it's the next container in the path for our currently
26810
+ // discovered providers.
26811
+ if (!visitedContainers.has(container)) {
26812
+ // Iterate through the providers we've already seen
26813
+ for (const prov of providerToPath.keys()) {
26814
+ const existingImportPath = providerToPath.get(prov);
26815
+ let containerDef = getInjectorDef(container);
26816
+ if (!containerDef) {
26817
+ const ngModule = container.ngModule;
26818
+ containerDef = getInjectorDef(ngModule);
26819
+ }
26820
+ if (!containerDef) {
26821
+ return;
26822
+ }
26823
+ const lastContainerAddedToPath = existingImportPath[0];
26824
+ let isNextStepInPath = false;
26825
+ deepForEach(containerDef.imports, (moduleImport) => {
26826
+ if (isNextStepInPath) {
26827
+ return;
26828
+ }
26829
+ isNextStepInPath = moduleImport.ngModule === lastContainerAddedToPath ||
26830
+ moduleImport === lastContainerAddedToPath;
26831
+ if (isNextStepInPath) {
26832
+ providerToPath.get(prov)?.unshift(container);
26833
+ }
26834
+ });
26835
+ }
26836
+ }
26837
+ visitedContainers.add(container);
26838
+ };
26839
+ }
26840
+ /**
26841
+ * Gets the providers configured on an EnvironmentInjector
26842
+ *
26843
+ * @param injector EnvironmentInjector
26844
+ * @returns an array of objects representing the providers of the given injector
26845
+ */
26846
+ function getEnvironmentInjectorProviders(injector) {
26847
+ const providerImportsContainer = getProviderImportsContainer(injector);
26848
+ if (providerImportsContainer === null) {
26849
+ throwError('Could not determine where injector providers were configured.');
26850
+ }
26851
+ const providerToPath = getProviderImportPaths(providerImportsContainer);
26852
+ const providerRecords = getFrameworkDIDebugData().resolverToProviders.get(injector) ?? [];
26853
+ return providerRecords.map(providerRecord => {
26854
+ let importPath = providerToPath.get(providerRecord.provider) ?? [providerImportsContainer];
26855
+ const def = getComponentDef(providerImportsContainer);
26856
+ const isStandaloneComponent = !!def?.standalone;
26857
+ // We prepend the component constructor in the standalone case
26858
+ // because walkProviderTree does not visit this constructor during it's traversal
26859
+ if (isStandaloneComponent) {
26860
+ importPath = [providerImportsContainer, ...providerToPath.get(providerRecord.provider) ?? []];
26861
+ }
26862
+ return { ...providerRecord, importPath };
26863
+ });
26864
+ }
26865
+ /**
26866
+ * Gets the providers configured on an injector.
26867
+ *
26868
+ * @param injector the injector to lookup the providers of
26869
+ * @returns ProviderRecord[] an array of objects representing the providers of the given injector
26870
+ */
26871
+ function getInjectorProviders(injector) {
26872
+ if (injector instanceof NodeInjector) {
26873
+ return getNodeInjectorProviders(injector);
26874
+ }
26875
+ else if (injector instanceof EnvironmentInjector) {
26876
+ return getEnvironmentInjectorProviders(injector);
26877
+ }
26878
+ throwError('getInjectorProviders only supports NodeInjector and EnvironmentInjector');
26879
+ }
26880
+ function getInjectorResolutionPath(injector) {
26881
+ const resolutionPath = [injector];
26882
+ getInjectorResolutionPathHelper(injector, resolutionPath);
26883
+ return resolutionPath;
26884
+ }
26885
+ function getInjectorResolutionPathHelper(injector, resolutionPath) {
26886
+ const parent = getInjectorParent(injector);
26887
+ // if getInjectorParent can't find a parent, then we've either reached the end
26888
+ // of the path, or we need to move from the Element Injector tree to the
26889
+ // module injector tree using the first injector in our path as the connection point.
26890
+ if (parent === null) {
26891
+ if (injector instanceof NodeInjector) {
26892
+ const firstInjector = resolutionPath[0];
26893
+ if (firstInjector instanceof NodeInjector) {
26894
+ const moduleInjector = getModuleInjectorOfNodeInjector(firstInjector);
26895
+ if (moduleInjector === null) {
26896
+ throwError('NodeInjector must have some connection to the module injector tree');
26897
+ }
26898
+ resolutionPath.push(moduleInjector);
26899
+ getInjectorResolutionPathHelper(moduleInjector, resolutionPath);
26900
+ }
26901
+ return resolutionPath;
26902
+ }
26903
+ }
26904
+ else {
26905
+ resolutionPath.push(parent);
26906
+ getInjectorResolutionPathHelper(parent, resolutionPath);
26907
+ }
26908
+ return resolutionPath;
26909
+ }
26910
+ /**
26911
+ * Gets the parent of an injector.
26912
+ *
26913
+ * This function is not able to make the jump from the Element Injector Tree to the Module
26914
+ * injector tree. This is because the "parent" (the next step in the reoslution path)
26915
+ * of a root NodeInjector is dependent on which NodeInjector ancestor initiated
26916
+ * the DI lookup. See getInjectorResolutionPath for a function that can make this jump.
26917
+ *
26918
+ * In the below diagram:
26919
+ * ```ts
26920
+ * getInjectorParent(NodeInjectorB)
26921
+ * > NodeInjectorA
26922
+ * getInjectorParent(NodeInjectorA) // or getInjectorParent(getInjectorParent(NodeInjectorB))
26923
+ * > null // cannot jump to ModuleInjector tree
26924
+ * ```
26925
+ *
26926
+ * ```
26927
+ * ┌───────┐ ┌───────────────────┐
26928
+ * ┌───────────┤ModuleA├───Injector────►│EnvironmentInjector│
26929
+ * │ └───┬───┘ └───────────────────┘
26930
+ * │ │
26931
+ * │ bootstraps
26932
+ * │ │
26933
+ * │ │
26934
+ * │ ┌────▼─────┐ ┌─────────────┐
26935
+ * declares │ComponentA├────Injector────►│NodeInjectorA│
26936
+ * │ └────┬─────┘ └─────▲───────┘
26937
+ * │ │ │
26938
+ * │ renders parent
26939
+ * │ │ │
26940
+ * │ ┌────▼─────┐ ┌─────┴───────┐
26941
+ * └─────────►│ComponentB├────Injector────►│NodeInjectorB│
26942
+ * └──────────┘ └─────────────┘
26943
+ *```
26944
+ *
26945
+ * @param injector an Injector to get the parent of
26946
+ * @returns Injector the parent of the given injector
26947
+ */
26948
+ function getInjectorParent(injector) {
26949
+ if (injector instanceof R3Injector) {
26950
+ return injector.parent;
26951
+ }
26952
+ let tNode;
26953
+ let lView;
26954
+ if (injector instanceof NodeInjector) {
26955
+ tNode = getNodeInjectorTNode(injector);
26956
+ lView = getNodeInjectorLView(injector);
26957
+ }
26958
+ else if (injector instanceof NullInjector) {
26959
+ return null;
26960
+ }
26961
+ else {
26962
+ throwError('getInjectorParent only support injectors of type R3Injector, NodeInjector, NullInjector');
26963
+ }
26964
+ const parentLocation = getParentInjectorLocation(tNode, lView);
26965
+ if (hasParentInjector(parentLocation)) {
26966
+ const parentInjectorIndex = getParentInjectorIndex(parentLocation);
26967
+ const parentLView = getParentInjectorView(parentLocation, lView);
26968
+ const parentTView = parentLView[TVIEW];
26969
+ const parentTNode = parentTView.data[parentInjectorIndex + 8 /* NodeInjectorOffset.TNODE */];
26970
+ return new NodeInjector(parentTNode, parentLView);
26971
+ }
26972
+ else {
26973
+ const chainedInjector = lView[INJECTOR$1];
26974
+ // Case where chainedInjector.injector is an OutletInjector and chainedInjector.injector.parent
26975
+ // is a NodeInjector.
26976
+ // todo(aleksanderbodurri): ideally nothing in packages/core should deal
26977
+ // directly with router concerns. Refactor this so that we can make the jump from
26978
+ // NodeInjector -> OutletInjector -> NodeInjector
26979
+ // without explictly relying on types contracts from packages/router
26980
+ const injectorParent = chainedInjector.injector?.parent;
26981
+ if (injectorParent instanceof NodeInjector) {
26982
+ return injectorParent;
26983
+ }
26984
+ }
26985
+ return null;
26986
+ }
26987
+ /**
26988
+ * Gets the module injector of a NodeInjector.
26989
+ *
26990
+ * @param injector NodeInjector to get module injector of
26991
+ * @returns Injector representing module injector of the given NodeInjector
26992
+ */
26993
+ function getModuleInjectorOfNodeInjector(injector) {
26994
+ let lView;
26995
+ if (injector instanceof NodeInjector) {
26996
+ lView = getNodeInjectorLView(injector);
26997
+ }
26998
+ else {
26999
+ throwError('getModuleInjectorOfNodeInjector must be called with a NodeInjector');
27000
+ }
27001
+ const chainedInjector = lView[INJECTOR$1];
27002
+ const moduleInjector = chainedInjector.parentInjector;
27003
+ if (!moduleInjector) {
27004
+ throwError('NodeInjector must have some connection to the module injector tree');
27005
+ }
27006
+ return moduleInjector;
27007
+ }
27008
+
25885
27009
  /**
25886
27010
  * This file introduces series of globally accessible debug tools
25887
27011
  * to allow for the Angular debugging story to function.
@@ -25907,6 +27031,10 @@ let _published = false;
25907
27031
  function publishDefaultGlobalUtils$1() {
25908
27032
  if (!_published) {
25909
27033
  _published = true;
27034
+ setupFrameworkInjectorProfiler();
27035
+ publishGlobalUtil('ɵgetDependenciesFromInjectable', getDependenciesFromInjectable);
27036
+ publishGlobalUtil('ɵgetInjectorProviders', getInjectorProviders);
27037
+ publishGlobalUtil('ɵgetInjectorResolutionPath', getInjectorResolutionPath);
25910
27038
  /**
25911
27039
  * Warning: this function is *INTERNAL* and should not be relied upon in application's code.
25912
27040
  * The contract of the function might be changed in any release and/or the function can be
@@ -29593,6 +30721,47 @@ function calcNumRootNodes(tView, lView, tNode) {
29593
30721
  collectNativeNodes(tView, lView, tNode, rootNodes);
29594
30722
  return rootNodes.length;
29595
30723
  }
30724
+ /**
30725
+ * Annotates root level component's LView for hydration,
30726
+ * see `annotateHostElementForHydration` for additional information.
30727
+ */
30728
+ function annotateComponentLViewForHydration(lView, context) {
30729
+ const hostElement = lView[HOST];
30730
+ // Root elements might also be annotated with the `ngSkipHydration` attribute,
30731
+ // check if it's present before starting the serialization process.
30732
+ if (hostElement && !hostElement.hasAttribute(SKIP_HYDRATION_ATTR_NAME)) {
30733
+ return annotateHostElementForHydration(hostElement, lView, context);
30734
+ }
30735
+ return null;
30736
+ }
30737
+ /**
30738
+ * Annotates root level LContainer for hydration. This happens when a root component
30739
+ * injects ViewContainerRef, thus making the component an anchor for a view container.
30740
+ * This function serializes the component itself as well as all views from the view
30741
+ * container.
30742
+ */
30743
+ function annotateLContainerForHydration(lContainer, context) {
30744
+ const componentLView = lContainer[HOST];
30745
+ // Serialize the root component itself.
30746
+ const componentLViewNghIndex = annotateComponentLViewForHydration(componentLView, context);
30747
+ const hostElement = unwrapRNode(componentLView[HOST]);
30748
+ // Serialize all views within this view container.
30749
+ const rootLView = lContainer[PARENT];
30750
+ const rootLViewNghIndex = annotateHostElementForHydration(hostElement, rootLView, context);
30751
+ const renderer = componentLView[RENDERER];
30752
+ // For cases when a root component also acts as an anchor node for a ViewContainerRef
30753
+ // (for example, when ViewContainerRef is injected in a root component), there is a need
30754
+ // to serialize information about the component itself, as well as an LContainer that
30755
+ // represents this ViewContainerRef. Effectively, we need to serialize 2 pieces of info:
30756
+ // (1) hydration info for the root component itself and (2) hydration info for the
30757
+ // ViewContainerRef instance (an LContainer). Each piece of information is included into
30758
+ // the hydration data (in the TransferState object) separately, thus we end up with 2 ids.
30759
+ // Since we only have 1 root element, we encode both bits of info into a single string:
30760
+ // ids are separated by the `|` char (e.g. `10|25`, where `10` is the ngh for a component view
30761
+ // and 25 is the `ngh` for a root view which holds LContainer).
30762
+ const finalIndex = `${componentLViewNghIndex}|${rootLViewNghIndex}`;
30763
+ renderer.setAttribute(hostElement, NGH_ATTR_NAME, finalIndex);
30764
+ }
29596
30765
  /**
29597
30766
  * Annotates all components bootstrapped in a given ApplicationRef
29598
30767
  * with info needed for hydration.
@@ -29605,21 +30774,21 @@ function annotateForHydration(appRef, doc) {
29605
30774
  const corruptedTextNodes = new Map();
29606
30775
  const viewRefs = appRef._views;
29607
30776
  for (const viewRef of viewRefs) {
29608
- const lView = getComponentLViewForHydration(viewRef);
30777
+ const lNode = getLNodeForHydration(viewRef);
29609
30778
  // An `lView` might be `null` if a `ViewRef` represents
29610
30779
  // an embedded view (not a component view).
29611
- if (lView !== null) {
29612
- const hostElement = lView[HOST];
29613
- // Root elements might also be annotated with the `ngSkipHydration` attribute,
29614
- // check if it's present before starting the serialization process.
29615
- if (hostElement && !hostElement.hasAttribute(SKIP_HYDRATION_ATTR_NAME)) {
29616
- const context = {
29617
- serializedViewCollection,
29618
- corruptedTextNodes,
29619
- };
29620
- annotateHostElementForHydration(hostElement, lView, context);
29621
- insertCorruptedTextNodeMarkers(corruptedTextNodes, doc);
30780
+ if (lNode !== null) {
30781
+ const context = {
30782
+ serializedViewCollection,
30783
+ corruptedTextNodes,
30784
+ };
30785
+ if (isLContainer(lNode)) {
30786
+ annotateLContainerForHydration(lNode, context);
30787
+ }
30788
+ else {
30789
+ annotateComponentLViewForHydration(lNode, context);
29622
30790
  }
30791
+ insertCorruptedTextNodeMarkers(corruptedTextNodes, doc);
29623
30792
  }
29624
30793
  }
29625
30794
  // Note: we *always* include hydration info key and a corresponding value
@@ -29900,6 +31069,8 @@ function componentUsesShadowDomEncapsulation(lView) {
29900
31069
  * @param element The Host element to be annotated
29901
31070
  * @param lView The associated LView
29902
31071
  * @param context The hydration context
31072
+ * @returns An index of serialized view from the transfer state object
31073
+ * or `null` when a given component can not be serialized.
29903
31074
  */
29904
31075
  function annotateHostElementForHydration(element, lView, context) {
29905
31076
  const renderer = lView[RENDERER];
@@ -29910,11 +31081,13 @@ function annotateHostElementForHydration(element, lView, context) {
29910
31081
  // shadow DOM, so we can not guarantee that client and server representations
29911
31082
  // would exactly match
29912
31083
  renderer.setAttribute(element, SKIP_HYDRATION_ATTR_NAME, '');
31084
+ return null;
29913
31085
  }
29914
31086
  else {
29915
31087
  const ngh = serializeLView(lView, context);
29916
31088
  const index = context.serializedViewCollection.add(ngh);
29917
31089
  renderer.setAttribute(element, NGH_ATTR_NAME, index.toString());
31090
+ return index;
29918
31091
  }
29919
31092
  }
29920
31093
  /**
@@ -29993,14 +31166,6 @@ function enableHydrationRuntimeSupport() {
29993
31166
  enableApplyRootElementTransformImpl();
29994
31167
  }
29995
31168
  }
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
31169
  /**
30005
31170
  * Outputs a message with hydration stats into a console.
30006
31171
  */
@@ -30049,7 +31214,7 @@ function withDomHydration() {
30049
31214
  provide: IS_HYDRATION_DOM_REUSE_ENABLED,
30050
31215
  useFactory: () => {
30051
31216
  let isEnabled = true;
30052
- if (isBrowser()) {
31217
+ if (isPlatformBrowser()) {
30053
31218
  // On the client, verify that the server response contains
30054
31219
  // hydration annotations. Otherwise, keep hydration disabled.
30055
31220
  const transferState = inject(TransferState, { optional: true });
@@ -30076,10 +31241,11 @@ function withDomHydration() {
30076
31241
  useValue: () => {
30077
31242
  // Since this function is used across both server and client,
30078
31243
  // make sure that the runtime code is only added when invoked
30079
- // on the client. Moving forward, the `isBrowser` check should
31244
+ // on the client. Moving forward, the `isPlatformBrowser` check should
30080
31245
  // be replaced with a tree-shakable alternative (e.g. `isServer`
30081
31246
  // flag).
30082
- if (isBrowser() && inject(IS_HYDRATION_DOM_REUSE_ENABLED)) {
31247
+ if (isPlatformBrowser() && inject(IS_HYDRATION_DOM_REUSE_ENABLED)) {
31248
+ verifySsrContentsIntegrity();
30083
31249
  enableHydrationRuntimeSupport();
30084
31250
  }
30085
31251
  },
@@ -30092,13 +31258,13 @@ function withDomHydration() {
30092
31258
  // environment and when hydration is configured properly.
30093
31259
  // On a server, an application is rendered from scratch,
30094
31260
  // so the host content needs to be empty.
30095
- return isBrowser() && inject(IS_HYDRATION_DOM_REUSE_ENABLED);
31261
+ return isPlatformBrowser() && inject(IS_HYDRATION_DOM_REUSE_ENABLED);
30096
31262
  }
30097
31263
  },
30098
31264
  {
30099
31265
  provide: APP_BOOTSTRAP_LISTENER,
30100
31266
  useFactory: () => {
30101
- if (isBrowser() && inject(IS_HYDRATION_DOM_REUSE_ENABLED)) {
31267
+ if (isPlatformBrowser() && inject(IS_HYDRATION_DOM_REUSE_ENABLED)) {
30102
31268
  const appRef = inject(ApplicationRef);
30103
31269
  const injector = inject(Injector);
30104
31270
  return () => {
@@ -30130,10 +31296,43 @@ function logWarningOnStableTimedout(time, console) {
30130
31296
  `as a signal to complete hydration process.`;
30131
31297
  console.warn(formatRuntimeError(-506 /* RuntimeErrorCode.HYDRATION_STABLE_TIMEDOUT */, message));
30132
31298
  }
31299
+ /**
31300
+ * Verifies whether the DOM contains a special marker added during SSR time to make sure
31301
+ * there is no SSR'ed contents transformations happen after SSR is completed. Typically that
31302
+ * happens either by CDN or during the build process as an optimization to remove comment nodes.
31303
+ * Hydration process requires comment nodes produced by Angular to locate correct DOM segments.
31304
+ * When this special marker is *not* present - throw an error and do not proceed with hydration,
31305
+ * since it will not be able to function correctly.
31306
+ *
31307
+ * Note: this function is invoked only on the client, so it's safe to use DOM APIs.
31308
+ */
31309
+ function verifySsrContentsIntegrity() {
31310
+ const doc = getDocument();
31311
+ let hydrationMarker;
31312
+ for (const node of doc.body.childNodes) {
31313
+ if (node.nodeType === Node.COMMENT_NODE &&
31314
+ node.textContent?.trim() === SSR_CONTENT_INTEGRITY_MARKER) {
31315
+ hydrationMarker = node;
31316
+ break;
31317
+ }
31318
+ }
31319
+ if (!hydrationMarker) {
31320
+ throw new RuntimeError(507 /* RuntimeErrorCode.MISSING_SSR_CONTENT_INTEGRITY_MARKER */, typeof ngDevMode !== 'undefined' && ngDevMode &&
31321
+ 'Angular hydration logic detected that HTML content of this page was modified after it ' +
31322
+ 'was produced during server side rendering. Make sure that there are no optimizations ' +
31323
+ 'that remove comment nodes from HTML are enabled on your CDN. Angular hydration ' +
31324
+ 'relies on HTML produced by the server, including whitespaces and comment nodes.');
31325
+ }
31326
+ }
30133
31327
 
30134
31328
  /**
30135
31329
  * Transforms a value (typically a string) to a boolean.
30136
31330
  * Intended to be used as a transform function of an input.
31331
+ *
31332
+ * @usageNotes
31333
+ * ```typescript
31334
+ * @Input({ transform: booleanAttribute }) status!: boolean;
31335
+ * ```
30137
31336
  * @param value Value to be transformed.
30138
31337
  *
30139
31338
  * @publicApi
@@ -30147,6 +31346,11 @@ function booleanAttribute(value) {
30147
31346
  * @param value Value to be transformed.
30148
31347
  * @param fallbackValue Value to use if the provided value can't be parsed as a number.
30149
31348
  *
31349
+ * @usageNotes
31350
+ * ```typescript
31351
+ * @Input({ transform: numberAttribute }) id!: number;
31352
+ * ```
31353
+ *
30150
31354
  * @publicApi
30151
31355
  */
30152
31356
  function numberAttribute(value, fallbackValue = NaN) {
@@ -30439,5 +31643,5 @@ if (typeof ngDevMode !== 'undefined' && ngDevMode) {
30439
31643
  * Generated bundle index. Do not edit.
30440
31644
  */
30441
31645
 
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 };
31646
+ 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, SSR_CONTENT_INTEGRITY_MARKER as ɵSSR_CONTENT_INTEGRITY_MARKER, 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
31647
  //# sourceMappingURL=core.mjs.map