@angular/core 16.1.0-next.0 → 16.1.0-next.2

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 (39) hide show
  1. package/esm2022/src/change_detection/change_detector_ref.mjs +2 -2
  2. package/esm2022/src/compiler/compiler_facade_interface.mjs +1 -1
  3. package/esm2022/src/core_private_export.mjs +1 -2
  4. package/esm2022/src/core_render3_private_export.mjs +2 -2
  5. package/esm2022/src/di/forward_ref.mjs +29 -2
  6. package/esm2022/src/di/r3_injector.mjs +6 -3
  7. package/esm2022/src/errors.mjs +1 -1
  8. package/esm2022/src/hydration/api.mjs +31 -3
  9. package/esm2022/src/i18n/locale_data_api.mjs +2 -2
  10. package/esm2022/src/interface/lifecycle_hooks.mjs +1 -1
  11. package/esm2022/src/render3/bindings.mjs +2 -2
  12. package/esm2022/src/render3/component.mjs +4 -4
  13. package/esm2022/src/render3/definition.mjs +6 -6
  14. package/esm2022/src/render3/di.mjs +5 -2
  15. package/esm2022/src/render3/errors.mjs +24 -3
  16. package/esm2022/src/render3/features/host_directives_feature.mjs +2 -2
  17. package/esm2022/src/render3/features/input_transforms_feature.mjs +13 -0
  18. package/esm2022/src/render3/index.mjs +3 -2
  19. package/esm2022/src/render3/instructions/listener.mjs +1 -3
  20. package/esm2022/src/render3/jit/environment.mjs +2 -1
  21. package/esm2022/src/render3/jit/module.mjs +11 -11
  22. package/esm2022/src/render3/node_manipulation.mjs +4 -2
  23. package/esm2022/src/signals/src/api.mjs +5 -3
  24. package/esm2022/src/transfer_state.mjs +7 -23
  25. package/esm2022/src/version.mjs +1 -1
  26. package/esm2022/testing/src/logger.mjs +3 -3
  27. package/esm2022/testing/src/test_bed_common.mjs +1 -1
  28. package/fesm2022/core.mjs +133 -60
  29. package/fesm2022/core.mjs.map +1 -1
  30. package/fesm2022/rxjs-interop.mjs +5 -3
  31. package/fesm2022/rxjs-interop.mjs.map +1 -1
  32. package/fesm2022/testing.mjs +99 -53
  33. package/fesm2022/testing.mjs.map +1 -1
  34. package/index.d.ts +56 -18
  35. package/package.json +1 -1
  36. package/rxjs-interop/index.d.ts +1 -1
  37. package/schematics/ng-generate/standalone-migration/bundle.js +362 -60
  38. package/schematics/ng-generate/standalone-migration/bundle.js.map +4 -4
  39. package/testing/index.d.ts +5 -5
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Angular v16.1.0-next.0
2
+ * @license Angular v16.1.0-next.2
3
3
  * (c) 2010-2022 Google LLC. https://angular.io/
4
4
  * License: MIT
5
5
  */
@@ -656,9 +656,36 @@ const __forward_ref__ = getClosureSafeProperty({ __forward_ref__: getClosureSafe
656
656
  * DI is declared, but not yet defined. It is also used when the `token` which we use when creating
657
657
  * a query is not yet defined.
658
658
  *
659
+ * `forwardRef` is also used to break circularities in standalone components imports.
660
+ *
659
661
  * @usageNotes
660
- * ### Example
662
+ * ### Circular dependency example
661
663
  * {@example core/di/ts/forward_ref/forward_ref_spec.ts region='forward_ref'}
664
+ *
665
+ * ### Circular standalone reference import example
666
+ * ```ts
667
+ * @Component({
668
+ * standalone: true,
669
+ * imports: [ChildComponent],
670
+ * selector: 'app-parent',
671
+ * template: `<app-child [hideParent]="hideParent"></app-child>`,
672
+ * })
673
+ * export class ParentComponent {
674
+ * @Input() hideParent: boolean;
675
+ * }
676
+ *
677
+ *
678
+ * @Component({
679
+ * standalone: true,
680
+ * imports: [CommonModule, forwardRef(() => ParentComponent)],
681
+ * selector: 'app-child',
682
+ * template: `<app-parent *ngIf="!hideParent"></app-parent>`,
683
+ * })
684
+ * export class ChildComponent {
685
+ * @Input() hideParent: boolean;
686
+ * }
687
+ * ```
688
+ *
662
689
  * @publicApi
663
690
  */
664
691
  function forwardRef(forwardRefFn) {
@@ -3085,7 +3112,7 @@ function getPipeDef$1(type) {
3085
3112
  /**
3086
3113
  * Checks whether a given Component, Directive or Pipe is marked as standalone.
3087
3114
  * This will return false if passed anything other than a Component, Directive, or Pipe class
3088
- * See this guide for additional information: https://angular.io/guide/standalone-components
3115
+ * See [this guide](/guide/standalone-components) for additional information:
3089
3116
  *
3090
3117
  * @param type A reference to a Component, Directive or Pipe.
3091
3118
  * @publicApi
@@ -3156,7 +3183,7 @@ function getComponentId(componentDef) {
3156
3183
  // Example:
3157
3184
  // https://github.com/angular/components/blob/d9f82c8f95309e77a6d82fd574c65871e91354c2/src/material/core/option/option.ts#L248
3158
3185
  // https://github.com/angular/components/blob/285f46dc2b4c5b127d356cb7c4714b221f03ce50/src/material/legacy-core/option/option.ts#L32
3159
- const hashSelectors = JSON.stringify([
3186
+ const hashSelectors = [
3160
3187
  componentDef.selectors,
3161
3188
  componentDef.ngContentSelectors,
3162
3189
  componentDef.hostVars,
@@ -3168,14 +3195,14 @@ function getComponentId(componentDef) {
3168
3195
  componentDef.standalone,
3169
3196
  componentDef.signals,
3170
3197
  componentDef.exportAs,
3171
- componentDef.inputs,
3172
- componentDef.outputs,
3198
+ JSON.stringify(componentDef.inputs),
3199
+ JSON.stringify(componentDef.outputs),
3173
3200
  // We cannot use 'componentDef.type.name' as the name of the symbol will change and will not
3174
3201
  // match in the server and browser bundles.
3175
3202
  Object.getOwnPropertyNames(componentDef.type.prototype),
3176
3203
  !!componentDef.contentQueries,
3177
3204
  !!componentDef.viewQuery,
3178
- ]);
3205
+ ].join('|');
3179
3206
  for (const char of hashSelectors) {
3180
3207
  hash = Math.imul(31, hash) + char.charCodeAt(0) << 0;
3181
3208
  }
@@ -3433,10 +3460,12 @@ function getFactoryDef(type, throwNotFound) {
3433
3460
  */
3434
3461
  const SIGNAL = Symbol('SIGNAL');
3435
3462
  /**
3436
- * Checks if the given `value` function is a reactive `Signal`.
3463
+ * Checks if the given `value` is a reactive `Signal`.
3464
+ *
3465
+ * @developerPreview
3437
3466
  */
3438
3467
  function isSignal(value) {
3439
- return value[SIGNAL] !== undefined;
3468
+ return typeof value === 'function' && value[SIGNAL] !== undefined;
3440
3469
  }
3441
3470
  /**
3442
3471
  * Converts `fn` into a marked signal function (where `isSignal(fn)` will be `true`), and
@@ -5684,7 +5713,10 @@ function getOrCreateInjectable(tNode, lView, token, flags = InjectFlags.Default,
5684
5713
  if (tNode !== null) {
5685
5714
  // If the view or any of its ancestors have an embedded
5686
5715
  // view injector, we have to look it up there first.
5687
- if (lView[FLAGS] & 2048 /* LViewFlags.HasEmbeddedViewInjector */) {
5716
+ if (lView[FLAGS] & 2048 /* LViewFlags.HasEmbeddedViewInjector */ &&
5717
+ // The token must be present on the current node injector when the `Self`
5718
+ // flag is set, so the lookup on embedded view injector(s) can be skipped.
5719
+ !(flags & InjectFlags.Self)) {
5688
5720
  const embeddedInjectorValue = lookupTokenUsingEmbeddedInjector(tNode, lView, token, flags, NOT_FOUND);
5689
5721
  if (embeddedInjectorValue !== NOT_FOUND) {
5690
5722
  return embeddedInjectorValue;
@@ -7462,12 +7494,14 @@ function processCleanups(tView, lView) {
7462
7494
  }
7463
7495
  const destroyHooks = lView[ON_DESTROY_HOOKS];
7464
7496
  if (destroyHooks !== null) {
7497
+ // Reset the ON_DESTROY_HOOKS array before iterating over it to prevent hooks that unregister
7498
+ // themselves from mutating the array during iteration.
7499
+ lView[ON_DESTROY_HOOKS] = null;
7465
7500
  for (let i = 0; i < destroyHooks.length; i++) {
7466
7501
  const destroyHooksFn = destroyHooks[i];
7467
7502
  ngDevMode && assertFunction(destroyHooksFn, 'Expecting destroy hook to be a function.');
7468
7503
  destroyHooksFn();
7469
7504
  }
7470
- lView[ON_DESTROY_HOOKS] = null;
7471
7505
  }
7472
7506
  }
7473
7507
  /** Calls onDestroy hooks for this view */
@@ -9464,7 +9498,11 @@ class R3Injector extends EnvironmentInjector {
9464
9498
  for (const service of this._ngOnDestroyHooks) {
9465
9499
  service.ngOnDestroy();
9466
9500
  }
9467
- for (const hook of this._onDestroyHooks) {
9501
+ const onDestroyHooks = this._onDestroyHooks;
9502
+ // Reset the _onDestroyHooks array before iterating over it to prevent hooks that unregister
9503
+ // themselves from mutating the array during iteration.
9504
+ this._onDestroyHooks = [];
9505
+ for (const hook of onDestroyHooks) {
9468
9506
  hook();
9469
9507
  }
9470
9508
  }
@@ -9473,7 +9511,6 @@ class R3Injector extends EnvironmentInjector {
9473
9511
  this.records.clear();
9474
9512
  this._ngOnDestroyHooks.clear();
9475
9513
  this.injectorDefTypes.clear();
9476
- this._onDestroyHooks.length = 0;
9477
9514
  }
9478
9515
  }
9479
9516
  onDestroy(callback) {
@@ -9887,26 +9924,6 @@ const ENABLED_SSR_FEATURES = new InjectionToken((typeof ngDevMode === 'undefined
9887
9924
  factory: () => new Set(),
9888
9925
  });
9889
9926
 
9890
- function escapeTransferStateContent(text) {
9891
- const escapedText = {
9892
- '&': '&a;',
9893
- '"': '&q;',
9894
- '\'': '&s;',
9895
- '<': '&l;',
9896
- '>': '&g;',
9897
- };
9898
- return text.replace(/[&"'<>]/g, s => escapedText[s]);
9899
- }
9900
- function unescapeTransferStateContent(text) {
9901
- const unescapedText = {
9902
- '&a;': '&',
9903
- '&q;': '"',
9904
- '&s;': '\'',
9905
- '&l;': '<',
9906
- '&g;': '>',
9907
- };
9908
- return text.replace(/&[^;]+;/g, s => unescapedText[s]);
9909
- }
9910
9927
  /**
9911
9928
  * Create a `StateKey<T>` that can be used to store value of type T with `TransferState`.
9912
9929
  *
@@ -10010,7 +10027,9 @@ class TransferState {
10010
10027
  }
10011
10028
  }
10012
10029
  }
10013
- return JSON.stringify(this.store);
10030
+ // Escape script tag to avoid break out of <script> tag in serialized output.
10031
+ // Encoding of `<` is the same behaviour as G3 script_builders.
10032
+ return JSON.stringify(this.store).replace(/</g, '\\u003C');
10014
10033
  }
10015
10034
  }
10016
10035
  function retrieveTransferredState(doc, appId) {
@@ -10020,7 +10039,9 @@ function retrieveTransferredState(doc, appId) {
10020
10039
  if (script?.textContent) {
10021
10040
  try {
10022
10041
  // Avoid using any here as it triggers lint errors in google3 (any is not allowed).
10023
- return JSON.parse(unescapeTransferStateContent(script.textContent));
10042
+ // Decoding of `<` is done of the box by browsers and node.js, same behaviour as G3
10043
+ // script_builders.
10044
+ return JSON.parse(script.textContent);
10024
10045
  }
10025
10046
  catch (e) {
10026
10047
  console.warn('Exception while restoring TransferState for app ' + appId, e);
@@ -10446,7 +10467,7 @@ class Version {
10446
10467
  /**
10447
10468
  * @publicApi
10448
10469
  */
10449
- const VERSION = new Version('16.1.0-next.0');
10470
+ const VERSION = new Version('16.1.0-next.2');
10450
10471
 
10451
10472
  // This default value is when checking the hierarchy for a token.
10452
10473
  //
@@ -10588,6 +10609,10 @@ function normalizeDebugBindingValue(value) {
10588
10609
  }
10589
10610
  }
10590
10611
 
10612
+ /**
10613
+ * The max length of the string representation of a value in an error message
10614
+ */
10615
+ const VALUE_STRING_LENGTH_LIMIT = 200;
10591
10616
  /** Verifies that a given type is a Standalone Component. */
10592
10617
  function assertStandaloneComponentType(type) {
10593
10618
  assertComponentDef(type);
@@ -10613,9 +10638,11 @@ function throwMultipleComponentError(tNode, first, second) {
10613
10638
  `${stringifyForError(second)}`);
10614
10639
  }
10615
10640
  /** Throws an ExpressionChangedAfterChecked error if checkNoChanges mode is on. */
10616
- function throwErrorIfNoChangesMode(creationMode, oldValue, currValue, propName) {
10641
+ function throwErrorIfNoChangesMode(creationMode, oldValue, currValue, propName, lView) {
10642
+ const hostComponentDef = getDeclarationComponentDef(lView);
10643
+ const componentClassName = hostComponentDef?.type?.name;
10617
10644
  const field = propName ? ` for '${propName}'` : '';
10618
- let msg = `ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value${field}: '${oldValue}'. Current value: '${currValue}'.`;
10645
+ let msg = `ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value${field}: '${formatValue(oldValue)}'. Current value: '${formatValue(currValue)}'.${componentClassName ? ` Expression location: ${componentClassName} component` : ''}`;
10619
10646
  if (creationMode) {
10620
10647
  msg +=
10621
10648
  ` It seems like the view has been created after its parent and its children have been dirty checked.` +
@@ -10623,6 +10650,20 @@ function throwErrorIfNoChangesMode(creationMode, oldValue, currValue, propName)
10623
10650
  }
10624
10651
  throw new RuntimeError(-100 /* RuntimeErrorCode.EXPRESSION_CHANGED_AFTER_CHECKED */, msg);
10625
10652
  }
10653
+ function formatValue(value) {
10654
+ let strValue = String(value);
10655
+ // JSON.stringify will throw on circular references
10656
+ try {
10657
+ if (Array.isArray(value) || strValue === '[object Object]') {
10658
+ strValue = JSON.stringify(value);
10659
+ }
10660
+ }
10661
+ catch (error) {
10662
+ }
10663
+ return strValue.length > VALUE_STRING_LENGTH_LIMIT ?
10664
+ (strValue.substring(0, VALUE_STRING_LENGTH_LIMIT) + '…') :
10665
+ strValue;
10666
+ }
10626
10667
  function constructDetailsForInterpolation(lView, rootIndex, expressionIndex, meta, changedValue) {
10627
10668
  const [propName, prefix, ...chunks] = meta.split(INTERPOLATION_DELIMITER);
10628
10669
  let oldValue = prefix, newValue = prefix;
@@ -13960,7 +14001,7 @@ function validateMappings(bindingType, def, hostDirectiveBindings) {
13960
14001
  throw new RuntimeError(311 /* RuntimeErrorCode.HOST_DIRECTIVE_UNDEFINED_BINDING */, `Directive ${className} does not have an ${bindingType} with a public name of ${publicName}.`);
13961
14002
  }
13962
14003
  const remappedPublicName = hostDirectiveBindings[publicName];
13963
- if (bindings.hasOwnProperty(remappedPublicName) &&
14004
+ if (bindings.hasOwnProperty(remappedPublicName) && remappedPublicName !== publicName &&
13964
14005
  bindings[remappedPublicName] !== publicName) {
13965
14006
  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.`);
13966
14007
  }
@@ -13968,6 +14009,12 @@ function validateMappings(bindingType, def, hostDirectiveBindings) {
13968
14009
  }
13969
14010
  }
13970
14011
 
14012
+ // TODO(crisbeto): move input transforms runtime functionality here.
14013
+ /**
14014
+ * @codeGenApi
14015
+ */
14016
+ function ɵɵInputTransformsFeature(definition) { }
14017
+
13971
14018
  function isIterable(obj) {
13972
14019
  return obj !== null && typeof obj === 'object' && obj[Symbol.iterator] !== undefined;
13973
14020
  }
@@ -14068,7 +14115,7 @@ function bindingUpdated(lView, bindingIndex, value) {
14068
14115
  const oldValueToCompare = oldValue !== NO_CHANGE ? oldValue : undefined;
14069
14116
  if (!devModeEqual(oldValueToCompare, value)) {
14070
14117
  const details = getExpressionChangedErrorDetails(lView, bindingIndex, oldValueToCompare, value);
14071
- throwErrorIfNoChangesMode(oldValue === NO_CHANGE, details.oldValue, details.newValue, details.propName);
14118
+ throwErrorIfNoChangesMode(oldValue === NO_CHANGE, details.oldValue, details.newValue, details.propName, lView);
14072
14119
  }
14073
14120
  // There was a change, but the `devModeEqual` decided that the change is exempt from an error.
14074
14121
  // For this reason we exit as if no change. The early exit is needed to prevent the changed
@@ -16053,8 +16100,6 @@ function wrapListener(tNode, lView, context, listenerFn, wrapWithPreventDefault)
16053
16100
  }
16054
16101
  if (wrapWithPreventDefault && result === false) {
16055
16102
  e.preventDefault();
16056
- // Necessary for legacy browsers that don't support preventDefault (e.g. IE)
16057
- e.returnValue = false;
16058
16103
  }
16059
16104
  return result;
16060
16105
  };
@@ -19587,7 +19632,7 @@ function getLocaleCurrencyCode(locale) {
19587
19632
  * @param locale A locale code for the locale format rules to use.
19588
19633
  * @returns The plural function for the locale.
19589
19634
  * @see `NgPlural`
19590
- * @see [Internationalization (i18n) Guide](https://angular.io/guide/i18n-overview)
19635
+ * @see [Internationalization (i18n) Guide](/guide/i18n-overview)
19591
19636
  */
19592
19637
  function getLocalePluralCase(locale) {
19593
19638
  const data = findLocaleData(locale);
@@ -24294,6 +24339,7 @@ const angularCoreEnv = (() => ({
24294
24339
  'ɵɵProvidersFeature': ɵɵProvidersFeature,
24295
24340
  'ɵɵCopyDefinitionFeature': ɵɵCopyDefinitionFeature,
24296
24341
  'ɵɵInheritDefinitionFeature': ɵɵInheritDefinitionFeature,
24342
+ 'ɵɵInputTransformsFeature': ɵɵInputTransformsFeature,
24297
24343
  'ɵɵStandaloneFeature': ɵɵStandaloneFeature,
24298
24344
  'ɵɵnextContext': ɵɵnextContext,
24299
24345
  'ɵɵnamespaceHTML': ɵɵnamespaceHTML,
@@ -24769,16 +24815,16 @@ function computeCombinedExports(type) {
24769
24815
  if (ngModuleDef === null) {
24770
24816
  return [type];
24771
24817
  }
24772
- return [...flatten$1(maybeUnwrapFn$1(ngModuleDef.exports).map((type) => {
24773
- const ngModuleDef = getNgModuleDef(type);
24774
- if (ngModuleDef) {
24775
- verifySemanticsOfNgModuleDef(type, false);
24776
- return computeCombinedExports(type);
24777
- }
24778
- else {
24779
- return type;
24780
- }
24781
- }))];
24818
+ return flatten$1(maybeUnwrapFn$1(ngModuleDef.exports).map((type) => {
24819
+ const ngModuleDef = getNgModuleDef(type);
24820
+ if (ngModuleDef) {
24821
+ verifySemanticsOfNgModuleDef(type, false);
24822
+ return computeCombinedExports(type);
24823
+ }
24824
+ else {
24825
+ return type;
24826
+ }
24827
+ }));
24782
24828
  }
24783
24829
  /**
24784
24830
  * Some declared components may be compiled asynchronously, and thus may not have their