@angular/core 16.0.2 → 16.0.4

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.
package/fesm2022/core.mjs CHANGED
@@ -1,11 +1,11 @@
1
1
  /**
2
- * @license Angular v16.0.2
2
+ * @license Angular v16.0.4
3
3
  * (c) 2010-2022 Google LLC. https://angular.io/
4
4
  * License: MIT
5
5
  */
6
6
 
7
- import { Subject, Subscription, Observable, merge as merge$1 } from 'rxjs';
8
- import { share, first } from 'rxjs/operators';
7
+ import { Subject, Subscription, BehaviorSubject, Observable, merge as merge$1, of } from 'rxjs';
8
+ import { share, mergeMap, distinctUntilChanged, first } from 'rxjs/operators';
9
9
 
10
10
  function getClosureSafeProperty(objWithPropertyToExtract) {
11
11
  for (let key in objWithPropertyToExtract) {
@@ -74,9 +74,36 @@ const __forward_ref__ = getClosureSafeProperty({ __forward_ref__: getClosureSafe
74
74
  * DI is declared, but not yet defined. It is also used when the `token` which we use when creating
75
75
  * a query is not yet defined.
76
76
  *
77
+ * `forwardRef` is also used to break circularities in standalone components imports.
78
+ *
77
79
  * @usageNotes
78
- * ### Example
80
+ * ### Circular dependency example
79
81
  * {@example core/di/ts/forward_ref/forward_ref_spec.ts region='forward_ref'}
82
+ *
83
+ * ### Circular standalone reference import example
84
+ * ```ts
85
+ * @Component({
86
+ * standalone: true,
87
+ * imports: [ChildComponent],
88
+ * selector: 'app-parent',
89
+ * template: `<app-child [hideParent]="hideParent"></app-child>`,
90
+ * })
91
+ * export class ParentComponent {
92
+ * @Input() hideParent: boolean;
93
+ * }
94
+ *
95
+ *
96
+ * @Component({
97
+ * standalone: true,
98
+ * imports: [CommonModule, forwardRef(() => ParentComponent)],
99
+ * selector: 'app-child',
100
+ * template: `<app-parent *ngIf="!hideParent"></app-parent>`,
101
+ * })
102
+ * export class ChildComponent {
103
+ * @Input() hideParent: boolean;
104
+ * }
105
+ * ```
106
+ *
80
107
  * @publicApi
81
108
  */
82
109
  function forwardRef(forwardRefFn) {
@@ -4419,7 +4446,10 @@ function getOrCreateInjectable(tNode, lView, token, flags = InjectFlags.Default,
4419
4446
  if (tNode !== null) {
4420
4447
  // If the view or any of its ancestors have an embedded
4421
4448
  // view injector, we have to look it up there first.
4422
- if (lView[FLAGS] & 2048 /* LViewFlags.HasEmbeddedViewInjector */) {
4449
+ if (lView[FLAGS] & 2048 /* LViewFlags.HasEmbeddedViewInjector */ &&
4450
+ // The token must be present on the current node injector when the `Self`
4451
+ // flag is set, so the lookup on embedded view injector(s) can be skipped.
4452
+ !(flags & InjectFlags.Self)) {
4423
4453
  const embeddedInjectorValue = lookupTokenUsingEmbeddedInjector(tNode, lView, token, flags, NOT_FOUND);
4424
4454
  if (embeddedInjectorValue !== NOT_FOUND) {
4425
4455
  return embeddedInjectorValue;
@@ -10038,7 +10068,7 @@ class Version {
10038
10068
  /**
10039
10069
  * @publicApi
10040
10070
  */
10041
- const VERSION = new Version('16.0.2');
10071
+ const VERSION = new Version('16.0.4');
10042
10072
 
10043
10073
  // This default value is when checking the hierarchy for a token.
10044
10074
  //
@@ -10228,6 +10258,10 @@ function maybeUnwrapFn(value) {
10228
10258
  }
10229
10259
  }
10230
10260
 
10261
+ /**
10262
+ * The max length of the string representation of a value in an error message
10263
+ */
10264
+ const VALUE_STRING_LENGTH_LIMIT = 200;
10231
10265
  /** Verifies that a given type is a Standalone Component. */
10232
10266
  function assertStandaloneComponentType(type) {
10233
10267
  assertComponentDef(type);
@@ -10257,7 +10291,7 @@ function throwErrorIfNoChangesMode(creationMode, oldValue, currValue, propName,
10257
10291
  const hostComponentDef = getDeclarationComponentDef(lView);
10258
10292
  const componentClassName = hostComponentDef?.type?.name;
10259
10293
  const field = propName ? ` for '${propName}'` : '';
10260
- let msg = `ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value${field}: '${oldValue}'. Current value: '${currValue}'.${componentClassName ? ` Expression location: ${componentClassName} component` : ''}`;
10294
+ let msg = `ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value${field}: '${formatValue(oldValue)}'. Current value: '${formatValue(currValue)}'.${componentClassName ? ` Expression location: ${componentClassName} component` : ''}`;
10261
10295
  if (creationMode) {
10262
10296
  msg +=
10263
10297
  ` It seems like the view has been created after its parent and its children have been dirty checked.` +
@@ -10265,6 +10299,20 @@ function throwErrorIfNoChangesMode(creationMode, oldValue, currValue, propName,
10265
10299
  }
10266
10300
  throw new RuntimeError(-100 /* RuntimeErrorCode.EXPRESSION_CHANGED_AFTER_CHECKED */, msg);
10267
10301
  }
10302
+ function formatValue(value) {
10303
+ let strValue = String(value);
10304
+ // JSON.stringify will throw on circular references
10305
+ try {
10306
+ if (Array.isArray(value) || strValue === '[object Object]') {
10307
+ strValue = JSON.stringify(value);
10308
+ }
10309
+ }
10310
+ catch (error) {
10311
+ }
10312
+ return strValue.length > VALUE_STRING_LENGTH_LIMIT ?
10313
+ (strValue.substring(0, VALUE_STRING_LENGTH_LIMIT) + '…') :
10314
+ strValue;
10315
+ }
10268
10316
  function constructDetailsForInterpolation(lView, rootIndex, expressionIndex, meta, changedValue) {
10269
10317
  const [propName, prefix, ...chunks] = meta.split(INTERPOLATION_DELIMITER);
10270
10318
  let oldValue = prefix, newValue = prefix;
@@ -13600,7 +13648,7 @@ function validateMappings(bindingType, def, hostDirectiveBindings) {
13600
13648
  throw new RuntimeError(311 /* RuntimeErrorCode.HOST_DIRECTIVE_UNDEFINED_BINDING */, `Directive ${className} does not have an ${bindingType} with a public name of ${publicName}.`);
13601
13649
  }
13602
13650
  const remappedPublicName = hostDirectiveBindings[publicName];
13603
- if (bindings.hasOwnProperty(remappedPublicName) &&
13651
+ if (bindings.hasOwnProperty(remappedPublicName) && remappedPublicName !== publicName &&
13604
13652
  bindings[remappedPublicName] !== publicName) {
13605
13653
  throw new RuntimeError(312 /* RuntimeErrorCode.HOST_DIRECTIVE_CONFLICTING_ALIAS */, `Cannot alias ${bindingType} ${publicName} of host directive ${className} to ${remappedPublicName}, because it already has a different ${bindingType} with the same public name.`);
13606
13654
  }
@@ -24427,16 +24475,16 @@ function computeCombinedExports(type) {
24427
24475
  if (ngModuleDef === null) {
24428
24476
  return [type];
24429
24477
  }
24430
- return [...flatten(maybeUnwrapFn(ngModuleDef.exports).map((type) => {
24431
- const ngModuleDef = getNgModuleDef(type);
24432
- if (ngModuleDef) {
24433
- verifySemanticsOfNgModuleDef(type, false);
24434
- return computeCombinedExports(type);
24435
- }
24436
- else {
24437
- return type;
24438
- }
24439
- }))];
24478
+ return flatten(maybeUnwrapFn(ngModuleDef.exports).map((type) => {
24479
+ const ngModuleDef = getNgModuleDef(type);
24480
+ if (ngModuleDef) {
24481
+ verifySemanticsOfNgModuleDef(type, false);
24482
+ return computeCombinedExports(type);
24483
+ }
24484
+ else {
24485
+ return type;
24486
+ }
24487
+ }));
24440
24488
  }
24441
24489
  /**
24442
24490
  * Some declared components may be compiled asynchronously, and thus may not have their
@@ -25558,6 +25606,45 @@ var MissingTranslationStrategy;
25558
25606
  MissingTranslationStrategy[MissingTranslationStrategy["Ignore"] = 2] = "Ignore";
25559
25607
  })(MissingTranslationStrategy || (MissingTranslationStrategy = {}));
25560
25608
 
25609
+ /**
25610
+ * *Internal* service that keeps track of pending tasks happening in the system
25611
+ * during the initial rendering. No tasks are tracked after an initial
25612
+ * rendering.
25613
+ *
25614
+ * This information is needed to make sure that the serialization on the server
25615
+ * is delayed until all tasks in the queue (such as an initial navigation or a
25616
+ * pending HTTP request) are completed.
25617
+ */
25618
+ class InitialRenderPendingTasks {
25619
+ constructor() {
25620
+ this.taskId = 0;
25621
+ this.pendingTasks = new Set();
25622
+ this.hasPendingTasks = new BehaviorSubject(false);
25623
+ }
25624
+ add() {
25625
+ this.hasPendingTasks.next(true);
25626
+ const taskId = this.taskId++;
25627
+ this.pendingTasks.add(taskId);
25628
+ return taskId;
25629
+ }
25630
+ remove(taskId) {
25631
+ this.pendingTasks.delete(taskId);
25632
+ if (this.pendingTasks.size === 0) {
25633
+ this.hasPendingTasks.next(false);
25634
+ }
25635
+ }
25636
+ ngOnDestroy() {
25637
+ this.pendingTasks.clear();
25638
+ this.hasPendingTasks.next(false);
25639
+ }
25640
+ static { this.ɵfac = function InitialRenderPendingTasks_Factory(t) { return new (t || InitialRenderPendingTasks)(); }; }
25641
+ static { this.ɵprov = /*@__PURE__*/ ɵɵdefineInjectable({ token: InitialRenderPendingTasks, factory: InitialRenderPendingTasks.ɵfac, providedIn: 'root' }); }
25642
+ }
25643
+ (function () { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(InitialRenderPendingTasks, [{
25644
+ type: Injectable,
25645
+ args: [{ providedIn: 'root' }]
25646
+ }], null, null); })();
25647
+
25561
25648
  /**
25562
25649
  * Combination of NgModuleFactory and ComponentFactories.
25563
25650
  *
@@ -27117,6 +27204,7 @@ class ApplicationRef {
27117
27204
  /** @internal */
27118
27205
  this._views = [];
27119
27206
  this.internalErrorHandler = inject(INTERNAL_APPLICATION_ERROR_HANDLER);
27207
+ this.zoneIsStable = inject(ZONE_IS_STABLE_OBSERVABLE);
27120
27208
  /**
27121
27209
  * Get a list of component types registered to this application.
27122
27210
  * This list is populated even before the component is created.
@@ -27129,7 +27217,8 @@ class ApplicationRef {
27129
27217
  /**
27130
27218
  * Returns an Observable that indicates when the application is stable or unstable.
27131
27219
  */
27132
- this.isStable = inject(ZONE_IS_STABLE_OBSERVABLE);
27220
+ this.isStable = inject(InitialRenderPendingTasks)
27221
+ .hasPendingTasks.pipe(mergeMap(hasPendingTasks => hasPendingTasks ? of(false) : this.zoneIsStable), distinctUntilChanged(), share());
27133
27222
  this._injector = inject(EnvironmentInjector);
27134
27223
  }
27135
27224
  /**
@@ -29743,69 +29832,6 @@ function isDisconnectedNode(tNode, lView) {
29743
29832
  !unwrapRNode(lView[tNode.index]).isConnected;
29744
29833
  }
29745
29834
 
29746
- /**
29747
- * *Internal* service that keeps track of pending tasks happening in the system
29748
- * during the initial rendering. No tasks are tracked after an initial
29749
- * rendering.
29750
- *
29751
- * This information is needed to make sure that the serialization on the server
29752
- * is delayed until all tasks in the queue (such as an initial navigation or a
29753
- * pending HTTP request) are completed.
29754
- */
29755
- class InitialRenderPendingTasks {
29756
- get whenAllTasksComplete() {
29757
- if (this.collection.size === 0) {
29758
- this.complete();
29759
- }
29760
- return this.promise;
29761
- }
29762
- constructor() {
29763
- this.taskId = 0;
29764
- this.collection = new Set();
29765
- this.ngZone = inject(NgZone);
29766
- this.completed = false;
29767
- // Run outside of the Angular zone to avoid triggering
29768
- // extra change detection cycles.
29769
- this.ngZone.runOutsideAngular(() => {
29770
- this.promise = new Promise((resolve) => {
29771
- this.resolve = resolve;
29772
- });
29773
- });
29774
- }
29775
- add() {
29776
- if (this.completed) {
29777
- // Indicates that the task was added after
29778
- // the task queue completion, so it's a noop.
29779
- return -1;
29780
- }
29781
- const taskId = this.taskId++;
29782
- this.collection.add(taskId);
29783
- return taskId;
29784
- }
29785
- remove(taskId) {
29786
- if (this.completed)
29787
- return;
29788
- this.collection.delete(taskId);
29789
- if (this.collection.size === 0) {
29790
- this.complete();
29791
- }
29792
- }
29793
- ngOnDestroy() {
29794
- this.complete();
29795
- this.collection.clear();
29796
- }
29797
- complete() {
29798
- this.completed = true;
29799
- this.resolve();
29800
- }
29801
- static { this.ɵfac = function InitialRenderPendingTasks_Factory(t) { return new (t || InitialRenderPendingTasks)(); }; }
29802
- static { this.ɵprov = /*@__PURE__*/ ɵɵdefineInjectable({ token: InitialRenderPendingTasks, factory: InitialRenderPendingTasks.ɵfac, providedIn: 'root' }); }
29803
- }
29804
- (function () { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(InitialRenderPendingTasks, [{
29805
- type: Injectable,
29806
- args: [{ providedIn: 'root' }]
29807
- }], function () { return []; }, null); })();
29808
-
29809
29835
  /**
29810
29836
  * Indicates whether the hydration-related code was added,
29811
29837
  * prevents adding it multiple times.
@@ -29864,7 +29890,7 @@ function printHydrationStats(injector) {
29864
29890
  /**
29865
29891
  * Returns a Promise that is resolved when an application becomes stable.
29866
29892
  */
29867
- function whenStable(appRef, pendingTasks, injector) {
29893
+ function whenStable(appRef, injector) {
29868
29894
  const isStablePromise = appRef.isStable.pipe(first((isStable) => isStable)).toPromise();
29869
29895
  if (typeof ngDevMode !== 'undefined' && ngDevMode) {
29870
29896
  const timeoutTime = APPLICATION_IS_STABLE_TIMEOUT;
@@ -29878,8 +29904,7 @@ function whenStable(appRef, pendingTasks, injector) {
29878
29904
  });
29879
29905
  isStablePromise.finally(() => clearTimeout(timeoutId));
29880
29906
  }
29881
- const pendingTasksPromise = pendingTasks.whenAllTasksComplete;
29882
- return Promise.allSettled([isStablePromise, pendingTasksPromise]);
29907
+ return isStablePromise.then(() => { });
29883
29908
  }
29884
29909
  /**
29885
29910
  * Returns a set of providers required to setup hydration support
@@ -29948,10 +29973,9 @@ function withDomHydration() {
29948
29973
  useFactory: () => {
29949
29974
  if (isBrowser() && inject(IS_HYDRATION_DOM_REUSE_ENABLED)) {
29950
29975
  const appRef = inject(ApplicationRef);
29951
- const pendingTasks = inject(InitialRenderPendingTasks);
29952
29976
  const injector = inject(Injector);
29953
29977
  return () => {
29954
- whenStable(appRef, pendingTasks, injector).then(() => {
29978
+ whenStable(appRef, injector).then(() => {
29955
29979
  // Wait until an app becomes stable and cleanup all views that
29956
29980
  // were not claimed during the application bootstrap process.
29957
29981
  // The timing is similar to when we start the serialization process