@angular/core 21.0.0-next.6 → 21.0.0-next.8

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 (77) hide show
  1. package/fesm2022/_attribute-chunk.mjs +2 -2
  2. package/fesm2022/_attribute-chunk.mjs.map +1 -1
  3. package/fesm2022/_debug_node-chunk.mjs +755 -141
  4. package/fesm2022/_debug_node-chunk.mjs.map +1 -1
  5. package/fesm2022/_effect-chunk.mjs +2 -2
  6. package/fesm2022/_effect-chunk.mjs.map +1 -1
  7. package/fesm2022/_not_found-chunk.mjs +2 -2
  8. package/fesm2022/_not_found-chunk.mjs.map +1 -1
  9. package/fesm2022/_resource-chunk.mjs +2 -2
  10. package/fesm2022/_resource-chunk.mjs.map +1 -1
  11. package/fesm2022/_root_effect_scheduler-chunk.mjs +8 -3
  12. package/fesm2022/_root_effect_scheduler-chunk.mjs.map +1 -1
  13. package/fesm2022/_signal-chunk.mjs +2 -2
  14. package/fesm2022/_signal-chunk.mjs.map +1 -1
  15. package/fesm2022/_weak_ref-chunk.mjs +2 -2
  16. package/fesm2022/_weak_ref-chunk.mjs.map +1 -1
  17. package/fesm2022/core.mjs +9 -13
  18. package/fesm2022/core.mjs.map +1 -1
  19. package/fesm2022/primitives-di.mjs +2 -2
  20. package/fesm2022/primitives-di.mjs.map +1 -1
  21. package/fesm2022/primitives-event-dispatch.mjs +2 -2
  22. package/fesm2022/primitives-event-dispatch.mjs.map +1 -1
  23. package/fesm2022/primitives-signals.mjs +2 -2
  24. package/fesm2022/primitives-signals.mjs.map +1 -1
  25. package/fesm2022/rxjs-interop.mjs +2 -2
  26. package/fesm2022/rxjs-interop.mjs.map +1 -1
  27. package/fesm2022/testing.mjs +2 -2
  28. package/fesm2022/testing.mjs.map +1 -1
  29. package/package.json +2 -2
  30. package/schematics/bundles/add-bootstrap-context-to-server-main.cjs +5 -5
  31. package/schematics/bundles/application-config-core.cjs +5 -5
  32. package/schematics/bundles/{apply_import_manager-pLtndDki.cjs → apply_import_manager-CBLmogDD.cjs} +3 -3
  33. package/schematics/bundles/bootstrap-options-migration.cjs +5 -5
  34. package/schematics/bundles/cleanup-unused-imports.cjs +5 -5
  35. package/schematics/bundles/{compiler_host-BJEh7-L1.cjs → compiler_host-T6xncpiw.cjs} +2 -2
  36. package/schematics/bundles/control-flow-migration.cjs +22 -21
  37. package/schematics/bundles/imports-DwPXlGFl.cjs +1 -1
  38. package/schematics/bundles/{index-DCfgOEYE.cjs → index-BnmACOsq.cjs} +237 -98
  39. package/schematics/bundles/{index-bqpULzLD.cjs → index-DWSaRJdz.cjs} +4 -4
  40. package/schematics/bundles/inject-migration.cjs +3 -3
  41. package/schematics/bundles/leading_space-D9nQ8UQC.cjs +1 -1
  42. package/schematics/bundles/{migrate_ts_type_references-COE6BA7E.cjs → migrate_ts_type_references-Cu-FR4L5.cjs} +47 -5
  43. package/schematics/bundles/{ng_component_template-pDoKlgPP.cjs → ng_component_template-BkWiUuGG.cjs} +2 -2
  44. package/schematics/bundles/ng_decorators-BI0uV7KI.cjs +1 -1
  45. package/schematics/bundles/ngclass-to-class-migration.cjs +7 -7
  46. package/schematics/bundles/ngstyle-to-style-migration.cjs +7 -7
  47. package/schematics/bundles/nodes-B16H9JUd.cjs +1 -1
  48. package/schematics/bundles/output-migration.cjs +6 -6
  49. package/schematics/bundles/{parse_html-B6fblY_V.cjs → parse_html-C97tKKp3.cjs} +2 -2
  50. package/schematics/bundles/{project_paths-i0Wjiiq1.cjs → project_paths-C6g3lqjX.cjs} +3 -3
  51. package/schematics/bundles/{project_tsconfig_paths-sFatqIE5.cjs → project_tsconfig_paths-CdhVNYMk.cjs} +401 -41
  52. package/schematics/bundles/property_name-BBwFuqMe.cjs +1 -1
  53. package/schematics/bundles/route-lazy-loading.cjs +3 -3
  54. package/schematics/bundles/router-current-navigation.cjs +4 -4
  55. package/schematics/bundles/router-last-successful-navigation.cjs +4 -4
  56. package/schematics/bundles/router-testing-module-migration.cjs +513 -0
  57. package/schematics/bundles/self-closing-tags-migration.cjs +6 -6
  58. package/schematics/bundles/signal-input-migration.cjs +7 -7
  59. package/schematics/bundles/signal-queries-migration.cjs +7 -7
  60. package/schematics/bundles/signals.cjs +7 -7
  61. package/schematics/bundles/standalone-migration.cjs +50 -10
  62. package/schematics/bundles/symbol-BObKoqes.cjs +1 -1
  63. package/schematics/collection.json +5 -0
  64. package/schematics/migrations/router-testing-module-migration/schema.json +14 -0
  65. package/types/_api-chunk.d.ts +2 -2
  66. package/types/_chrome_dev_tools_performance-chunk.d.ts +4 -2
  67. package/types/_discovery-chunk.d.ts +61 -12
  68. package/types/_effect-chunk.d.ts +2 -2
  69. package/types/_event_dispatcher-chunk.d.ts +2 -2
  70. package/types/_formatter-chunk.d.ts +2 -2
  71. package/types/_weak_ref-chunk.d.ts +2 -2
  72. package/types/core.d.ts +135 -11
  73. package/types/primitives-di.d.ts +2 -2
  74. package/types/primitives-event-dispatch.d.ts +2 -2
  75. package/types/primitives-signals.d.ts +2 -2
  76. package/types/rxjs-interop.d.ts +2 -2
  77. package/types/testing.d.ts +2 -2
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
  /**
3
- * @license Angular v21.0.0-next.6
3
+ * @license Angular v21.0.0-next.8
4
4
  * (c) 2010-2025 Google LLC. https://angular.io/
5
5
  * License: MIT
6
6
  */
@@ -2725,6 +2725,8 @@ class Identifiers {
2725
2725
  static domProperty = { name: 'ɵɵdomProperty', moduleName: CORE };
2726
2726
  static ariaProperty = { name: 'ɵɵariaProperty', moduleName: CORE };
2727
2727
  static property = { name: 'ɵɵproperty', moduleName: CORE };
2728
+ static control = { name: 'ɵɵcontrol', moduleName: CORE };
2729
+ static controlCreate = { name: 'ɵɵcontrolCreate', moduleName: CORE };
2728
2730
  static animationEnterListener = {
2729
2731
  name: 'ɵɵanimateEnterListener',
2730
2732
  moduleName: CORE,
@@ -2905,6 +2907,16 @@ class Identifiers {
2905
2907
  name: 'ɵɵvalidateIframeAttribute',
2906
2908
  moduleName: CORE,
2907
2909
  };
2910
+ // Decorators
2911
+ static inputDecorator = { name: 'Input', moduleName: CORE };
2912
+ static outputDecorator = { name: 'Output', moduleName: CORE };
2913
+ static viewChildDecorator = { name: 'ViewChild', moduleName: CORE };
2914
+ static viewChildrenDecorator = { name: 'ViewChildren', moduleName: CORE };
2915
+ static contentChildDecorator = { name: 'ContentChild', moduleName: CORE };
2916
+ static contentChildrenDecorator = {
2917
+ name: 'ContentChildren',
2918
+ moduleName: CORE,
2919
+ };
2908
2920
  // type-checking
2909
2921
  static InputSignalBrandWriteType = { name: 'ɵINPUT_SIGNAL_BRAND_WRITE_TYPE', moduleName: CORE };
2910
2922
  static UnwrapDirectiveSignalInputs = { name: 'ɵUnwrapDirectiveSignalInputs', moduleName: CORE };
@@ -4831,9 +4843,11 @@ class InteractionDeferredTrigger extends DeferredTrigger {
4831
4843
  }
4832
4844
  class ViewportDeferredTrigger extends DeferredTrigger {
4833
4845
  reference;
4834
- constructor(reference, nameSpan, sourceSpan, prefetchSpan, onSourceSpan, hydrateSpan) {
4846
+ options;
4847
+ constructor(reference, options, nameSpan, sourceSpan, prefetchSpan, onSourceSpan, hydrateSpan) {
4835
4848
  super(nameSpan, sourceSpan, prefetchSpan, onSourceSpan, hydrateSpan);
4836
4849
  this.reference = reference;
4850
+ this.options = options;
4837
4851
  }
4838
4852
  }
4839
4853
  class BlockNode {
@@ -8657,6 +8671,17 @@ var OpKind;
8657
8671
  * An operation to bind animation events to an element.
8658
8672
  */
8659
8673
  OpKind[OpKind["AnimationListener"] = 56] = "AnimationListener";
8674
+ /**
8675
+ * An operation to bind an expression to a `field` property of an element.
8676
+ */
8677
+ OpKind[OpKind["Control"] = 57] = "Control";
8678
+ /**
8679
+ * An operation to set up a corresponding {@link Control} operation.
8680
+ *
8681
+ * This is responsible for setting up event listeners on a native or custom form control when
8682
+ * bound to a specialized field directive.
8683
+ */
8684
+ OpKind[OpKind["ControlCreate"] = 58] = "ControlCreate";
8660
8685
  })(OpKind || (OpKind = {}));
8661
8686
  /**
8662
8687
  * Distinguishes different kinds of IR expressions.
@@ -9327,6 +9352,25 @@ function createStoreLetOp(target, declaredName, value, sourceSpan) {
9327
9352
  ...NEW_OP,
9328
9353
  };
9329
9354
  }
9355
+ /** Creates a {@link ControlOp}. */
9356
+ function createControlOp(op) {
9357
+ return {
9358
+ kind: OpKind.Control,
9359
+ target: op.target,
9360
+ expression: op.expression,
9361
+ bindingKind: op.bindingKind,
9362
+ securityContext: op.securityContext,
9363
+ sanitizer: null,
9364
+ isStructuralTemplateAttribute: op.isStructuralTemplateAttribute,
9365
+ templateKind: op.templateKind,
9366
+ i18nContext: op.i18nContext,
9367
+ i18nMessage: op.i18nMessage,
9368
+ sourceSpan: op.sourceSpan,
9369
+ ...TRAIT_DEPENDS_ON_SLOT_CONTEXT,
9370
+ ...TRAIT_CONSUMES_VARS,
9371
+ ...NEW_OP,
9372
+ };
9373
+ }
9330
9374
 
9331
9375
  /**
9332
9376
  * Check whether a given `o.Expression` is a logical IR expression type.
@@ -10109,6 +10153,7 @@ function transformExpressionsInOp(op, transform, flags) {
10109
10153
  case OpKind.Property:
10110
10154
  case OpKind.DomProperty:
10111
10155
  case OpKind.Attribute:
10156
+ case OpKind.Control:
10112
10157
  if (op.expression instanceof Interpolation) {
10113
10158
  transformExpressionsInInterpolation(op.expression, transform, flags);
10114
10159
  }
@@ -10234,6 +10279,7 @@ function transformExpressionsInOp(op, transform, flags) {
10234
10279
  case OpKind.SourceLocation:
10235
10280
  case OpKind.ConditionalCreate:
10236
10281
  case OpKind.ConditionalBranchCreate:
10282
+ case OpKind.ControlCreate:
10237
10283
  // These operations contain no expressions.
10238
10284
  break;
10239
10285
  default:
@@ -11134,6 +11180,10 @@ function createSourceLocationOp(templatePath, locations) {
11134
11180
  ...NEW_OP,
11135
11181
  };
11136
11182
  }
11183
+ /** Creates a {@link ControlCreateOp}. */
11184
+ function createControlCreateOp(sourceSpan) {
11185
+ return { kind: OpKind.ControlCreate, sourceSpan, ...NEW_OP };
11186
+ }
11137
11187
 
11138
11188
  function createDomPropertyOp(name, expression, bindingKind, i18nContext, securityContext, sourceSpan) {
11139
11189
  return {
@@ -11612,6 +11662,14 @@ function extractAttributes(job) {
11612
11662
  /* i18nMessage */ null, op.securityContext), lookupElement$3(elements, op.target));
11613
11663
  }
11614
11664
  break;
11665
+ case OpKind.Control:
11666
+ OpList.insertBefore(
11667
+ // Deliberately null i18nMessage value
11668
+ createExtractedAttributeOp(op.target, BindingKind.Property, null, 'field',
11669
+ /* expression */ null,
11670
+ /* i18nContext */ null,
11671
+ /* i18nMessage */ null, op.securityContext), lookupElement$3(elements, op.target));
11672
+ break;
11615
11673
  case OpKind.TwoWayProperty:
11616
11674
  OpList.insertBefore(createExtractedAttributeOp(op.target, BindingKind.TwoWayProperty, null, op.name,
11617
11675
  /* expression */ null,
@@ -11771,6 +11829,9 @@ function specializeBindings(job) {
11771
11829
  else if (job.kind === CompilationJobKind.Host) {
11772
11830
  OpList.replace(op, createDomPropertyOp(op.name, op.expression, op.bindingKind, op.i18nContext, op.securityContext, op.sourceSpan));
11773
11831
  }
11832
+ else if (op.name === 'field') {
11833
+ OpList.replace(op, createControlOp(op));
11834
+ }
11774
11835
  else {
11775
11836
  OpList.replace(op, createPropertyOp(op.target, op.name, op.expression, op.bindingKind, op.securityContext, op.isStructuralTemplateAttribute, op.templateKind, op.i18nContext, op.i18nMessage, op.sourceSpan));
11776
11837
  }
@@ -23620,7 +23681,7 @@ function deferOn(trigger, args, modifier, sourceSpan) {
23620
23681
  if (instructionToCall === undefined) {
23621
23682
  throw new Error(`Unable to determine instruction for trigger ${trigger}`);
23622
23683
  }
23623
- return call(instructionToCall, args.map((a) => literal(a)), sourceSpan);
23684
+ return call(instructionToCall, args, sourceSpan);
23624
23685
  }
23625
23686
  function projectionDef(def) {
23626
23687
  return call(Identifiers.projectionDef, def ? [def] : [], null);
@@ -23749,6 +23810,22 @@ function ariaProperty(name, expression, sourceSpan) {
23749
23810
  function property(name, expression, sanitizer, sourceSpan) {
23750
23811
  return propertyBase(Identifiers.property, name, expression, sanitizer, sourceSpan);
23751
23812
  }
23813
+ function control(expression, sanitizer, sourceSpan) {
23814
+ const args = [];
23815
+ if (expression instanceof Interpolation) {
23816
+ args.push(interpolationToExpression(expression, sourceSpan));
23817
+ }
23818
+ else {
23819
+ args.push(expression);
23820
+ }
23821
+ if (sanitizer !== null) {
23822
+ args.push(sanitizer);
23823
+ }
23824
+ return call(Identifiers.control, args, sourceSpan);
23825
+ }
23826
+ function controlCreate(sourceSpan) {
23827
+ return call(Identifiers.controlCreate, [], sourceSpan);
23828
+ }
23752
23829
  function twoWayProperty(name, expression, sanitizer, sourceSpan) {
23753
23830
  const args = [literal(name), expression];
23754
23831
  if (sanitizer !== null) {
@@ -24195,11 +24272,30 @@ function reifyCreateOperations(unit, ops) {
24195
24272
  case DeferTriggerKind.Immediate:
24196
24273
  break;
24197
24274
  case DeferTriggerKind.Timer:
24198
- args = [op.trigger.delay];
24275
+ args = [literal(op.trigger.delay)];
24276
+ break;
24277
+ case DeferTriggerKind.Viewport:
24278
+ // `hydrate` triggers don't support targets.
24279
+ if (op.modifier === "hydrate" /* ir.DeferOpModifierKind.HYDRATE */) {
24280
+ args = op.trigger.options ? [op.trigger.options] : [];
24281
+ }
24282
+ else {
24283
+ // The slots not being defined at this point is invalid, however we
24284
+ // catch it during type checking. Pass in null in such cases.
24285
+ args = [literal(op.trigger.targetSlot?.slot ?? null)];
24286
+ if (op.trigger.targetSlotViewSteps !== 0) {
24287
+ args.push(literal(op.trigger.targetSlotViewSteps));
24288
+ }
24289
+ else if (op.trigger.options) {
24290
+ args.push(literal(null));
24291
+ }
24292
+ if (op.trigger.options) {
24293
+ args.push(op.trigger.options);
24294
+ }
24295
+ }
24199
24296
  break;
24200
24297
  case DeferTriggerKind.Interaction:
24201
24298
  case DeferTriggerKind.Hover:
24202
- case DeferTriggerKind.Viewport:
24203
24299
  // `hydrate` triggers don't support targets.
24204
24300
  if (op.modifier === "hydrate" /* ir.DeferOpModifierKind.HYDRATE */) {
24205
24301
  args = [];
@@ -24207,9 +24303,9 @@ function reifyCreateOperations(unit, ops) {
24207
24303
  else {
24208
24304
  // The slots not being defined at this point is invalid, however we
24209
24305
  // catch it during type checking. Pass in null in such cases.
24210
- args = [op.trigger.targetSlot?.slot ?? null];
24306
+ args = [literal(op.trigger.targetSlot?.slot ?? null)];
24211
24307
  if (op.trigger.targetSlotViewSteps !== 0) {
24212
- args.push(op.trigger.targetSlotViewSteps);
24308
+ args.push(literal(op.trigger.targetSlotViewSteps));
24213
24309
  }
24214
24310
  }
24215
24311
  break;
@@ -24309,6 +24405,9 @@ function reifyCreateOperations(unit, ops) {
24309
24405
  }));
24310
24406
  OpList.replace(op, attachSourceLocation(op.templatePath, locationsLiteral));
24311
24407
  break;
24408
+ case OpKind.ControlCreate:
24409
+ OpList.replace(op, controlCreate(op.sourceSpan));
24410
+ break;
24312
24411
  case OpKind.Statement:
24313
24412
  // Pass statement operations directly through.
24314
24413
  break;
@@ -24331,6 +24430,9 @@ function reifyUpdateOperations(unit, ops) {
24331
24430
  ? reifyDomProperty(op)
24332
24431
  : reifyProperty(op));
24333
24432
  break;
24433
+ case OpKind.Control:
24434
+ OpList.replace(op, reifyControl(op));
24435
+ break;
24334
24436
  case OpKind.TwoWayProperty:
24335
24437
  OpList.replace(op, twoWayProperty(op.name, op.expression, op.sanitizer, op.sourceSpan));
24336
24438
  break;
@@ -24426,6 +24528,9 @@ function reifyProperty(op) {
24426
24528
  ? ariaProperty(op.name, op.expression, op.sourceSpan)
24427
24529
  : property(op.name, op.expression, op.sanitizer, op.sourceSpan);
24428
24530
  }
24531
+ function reifyControl(op) {
24532
+ return control(op.expression, op.sanitizer, op.sourceSpan);
24533
+ }
24429
24534
  function reifyIrExpression(expr) {
24430
24535
  if (!isIrExpression(expr)) {
24431
24536
  return expr;
@@ -25938,6 +26043,7 @@ function varsUsedByOp(op) {
25938
26043
  return slots;
25939
26044
  case OpKind.Property:
25940
26045
  case OpKind.DomProperty:
26046
+ case OpKind.Control:
25941
26047
  slots = 1;
25942
26048
  // We need to assign a slot even for singleton interpolations, because the
25943
26049
  // runtime needs to store both the raw value and the stringified one.
@@ -27075,6 +27181,9 @@ function ingestDeferTriggers(modifier, triggers, onOps, whenOps, unit, deferXref
27075
27181
  targetSlot: null,
27076
27182
  targetView: null,
27077
27183
  targetSlotViewSteps: null,
27184
+ options: triggers.viewport.options
27185
+ ? convertAst(triggers.viewport.options, unit.job, triggers.viewport.sourceSpan)
27186
+ : null,
27078
27187
  }, modifier, triggers.viewport.sourceSpan);
27079
27188
  onOps.push(deferOnOp);
27080
27189
  }
@@ -27405,6 +27514,11 @@ function ingestElementBindings(unit, op, element) {
27405
27514
  }
27406
27515
  // All dynamic bindings (both attribute and property bindings).
27407
27516
  bindings.push(createBindingOp(op.xref, BINDING_KINDS.get(input.type), input.name, convertAstWithInterpolation(unit.job, astOf(input.value), input.i18n), input.unit, input.securityContext, false, false, null, asMessage(input.i18n) ?? null, input.sourceSpan));
27517
+ // If the input name is 'field', this could be a form control binding which requires a
27518
+ // `ControlCreateOp` to properly initialize.
27519
+ if (input.type === exports.BindingType.Property && input.name === 'field') {
27520
+ unit.create.push(createControlCreateOp(input.sourceSpan));
27521
+ }
27408
27522
  }
27409
27523
  unit.create.push(bindings.filter((b) => b?.kind === OpKind.ExtractedAttribute));
27410
27524
  unit.update.push(bindings.filter((b) => b?.kind === OpKind.Binding));
@@ -28581,6 +28695,7 @@ function createForLoop(ast, connectedBlocks, visitor, bindingParser) {
28581
28695
  // main `for` body, use `mainSourceSpan`.
28582
28696
  const endSpan = empty?.endSourceSpan ?? ast.endSourceSpan;
28583
28697
  const sourceSpan = new ParseSourceSpan(ast.sourceSpan.start, endSpan?.end ?? ast.sourceSpan.end);
28698
+ validateTrackByExpression(params.trackBy.expression, params.trackBy.keywordSpan, errors);
28584
28699
  node = new ForLoopBlock(params.itemName, params.expression, params.trackBy.expression, params.trackBy.keywordSpan, params.context, visitAll(visitor, ast.children, ast.children), empty, sourceSpan, ast.sourceSpan, ast.startSourceSpan, endSpan, ast.nameSpan, ast.i18n);
28585
28700
  }
28586
28701
  }
@@ -28680,6 +28795,13 @@ function parseForLoopParameters(block, errors, bindingParser) {
28680
28795
  }
28681
28796
  return result;
28682
28797
  }
28798
+ function validateTrackByExpression(expression, parseSourceSpan, errors) {
28799
+ const visitor = new PipeVisitor();
28800
+ expression.ast.visit(visitor);
28801
+ if (visitor.hasPipe) {
28802
+ errors.push(new ParseError(parseSourceSpan, 'Cannot use pipes in track expressions'));
28803
+ }
28804
+ }
28683
28805
  /** Parses the `let` parameter of a `for` loop block. */
28684
28806
  function parseLetParameter(sourceSpan, expression, span, loopItemName, context, errors) {
28685
28807
  const parts = expression.split(',');
@@ -28890,6 +29012,12 @@ function stripOptionalParentheses(param, errors) {
28890
29012
  }
28891
29013
  return expression.slice(start, end);
28892
29014
  }
29015
+ class PipeVisitor extends RecursiveAstVisitor {
29016
+ hasPipe = false;
29017
+ visitPipe() {
29018
+ this.hasPipe = true;
29019
+ }
29020
+ }
28893
29021
 
28894
29022
  /** Pattern for a timing value in a trigger. */
28895
29023
  const TIME_PATTERN = /^\d+\.?\d*(ms|s)?$/;
@@ -28945,7 +29073,7 @@ function parseWhenTrigger({ expression, sourceSpan }, bindingParser, triggers, e
28945
29073
  }
28946
29074
  }
28947
29075
  /** Parses an `on` trigger */
28948
- function parseOnTrigger({ expression, sourceSpan }, triggers, errors, placeholder) {
29076
+ function parseOnTrigger({ expression, sourceSpan }, bindingParser, triggers, errors, placeholder) {
28949
29077
  const onIndex = expression.indexOf('on');
28950
29078
  const onSourceSpan = new ParseSourceSpan(sourceSpan.start.moveBy(onIndex), sourceSpan.start.moveBy(onIndex + 'on'.length));
28951
29079
  const prefetchSpan = getPrefetchSpan(expression, sourceSpan);
@@ -28957,9 +29085,10 @@ function parseOnTrigger({ expression, sourceSpan }, triggers, errors, placeholde
28957
29085
  }
28958
29086
  else {
28959
29087
  const start = getTriggerParametersStart(expression, onIndex + 1);
28960
- const parser = new OnTriggerParser(expression, start, sourceSpan, triggers, errors, expression.startsWith('hydrate')
29088
+ const isHydrationTrigger = expression.startsWith('hydrate');
29089
+ const parser = new OnTriggerParser(expression, bindingParser, start, sourceSpan, triggers, errors, isHydrationTrigger
28961
29090
  ? validateHydrateReferenceBasedTrigger
28962
- : validatePlainReferenceBasedTrigger, placeholder, prefetchSpan, onSourceSpan, hydrateSpan);
29091
+ : validatePlainReferenceBasedTrigger, isHydrationTrigger, prefetchSpan, onSourceSpan, hydrateSpan);
28963
29092
  parser.parse();
28964
29093
  }
28965
29094
  }
@@ -28977,25 +29106,27 @@ function getHydrateSpan(expression, sourceSpan) {
28977
29106
  }
28978
29107
  class OnTriggerParser {
28979
29108
  expression;
29109
+ bindingParser;
28980
29110
  start;
28981
29111
  span;
28982
29112
  triggers;
28983
29113
  errors;
28984
29114
  validator;
28985
- placeholder;
29115
+ isHydrationTrigger;
28986
29116
  prefetchSpan;
28987
29117
  onSourceSpan;
28988
29118
  hydrateSpan;
28989
29119
  index = 0;
28990
29120
  tokens;
28991
- constructor(expression, start, span, triggers, errors, validator, placeholder, prefetchSpan, onSourceSpan, hydrateSpan) {
29121
+ constructor(expression, bindingParser, start, span, triggers, errors, validator, isHydrationTrigger, prefetchSpan, onSourceSpan, hydrateSpan) {
28992
29122
  this.expression = expression;
29123
+ this.bindingParser = bindingParser;
28993
29124
  this.start = start;
28994
29125
  this.span = span;
28995
29126
  this.triggers = triggers;
28996
29127
  this.errors = errors;
28997
29128
  this.validator = validator;
28998
- this.placeholder = placeholder;
29129
+ this.isHydrationTrigger = isHydrationTrigger;
28999
29130
  this.prefetchSpan = prefetchSpan;
29000
29131
  this.onSourceSpan = onSourceSpan;
29001
29132
  this.hydrateSpan = hydrateSpan;
@@ -29069,10 +29200,10 @@ class OnTriggerParser {
29069
29200
  this.trackTrigger('immediate', createImmediateTrigger(parameters, nameSpan, sourceSpan, this.prefetchSpan, this.onSourceSpan, this.hydrateSpan));
29070
29201
  break;
29071
29202
  case OnTriggerType.HOVER:
29072
- this.trackTrigger('hover', createHoverTrigger(parameters, nameSpan, sourceSpan, this.prefetchSpan, this.onSourceSpan, this.hydrateSpan, this.placeholder, this.validator));
29203
+ this.trackTrigger('hover', createHoverTrigger(parameters, nameSpan, sourceSpan, this.prefetchSpan, this.onSourceSpan, this.hydrateSpan, this.validator));
29073
29204
  break;
29074
29205
  case OnTriggerType.VIEWPORT:
29075
- this.trackTrigger('viewport', createViewportTrigger(parameters, nameSpan, sourceSpan, this.prefetchSpan, this.onSourceSpan, this.hydrateSpan, this.validator));
29206
+ this.trackTrigger('viewport', createViewportTrigger(this.start, this.isHydrationTrigger, this.bindingParser, parameters, nameSpan, sourceSpan, this.prefetchSpan, this.onSourceSpan, this.hydrateSpan, this.validator));
29076
29207
  break;
29077
29208
  default:
29078
29209
  throw new Error(`Unrecognized trigger type "${identifier}"`);
@@ -29090,15 +29221,15 @@ class OnTriggerParser {
29090
29221
  }
29091
29222
  this.advance();
29092
29223
  const commaDelimStack = [];
29093
- let current = '';
29224
+ let tokens = [];
29094
29225
  while (this.index < this.tokens.length) {
29095
29226
  const token = this.token();
29096
29227
  // Stop parsing if we've hit the end character and we're outside of a comma-delimited syntax.
29097
29228
  // Note that we don't need to account for strings here since the lexer already parsed them
29098
29229
  // into string tokens.
29099
29230
  if (token.isCharacter($RPAREN) && commaDelimStack.length === 0) {
29100
- if (current.length) {
29101
- parameters.push(current);
29231
+ if (tokens.length) {
29232
+ parameters.push({ expression: this.tokenRangeText(tokens), start: tokens[0].index });
29102
29233
  }
29103
29234
  break;
29104
29235
  }
@@ -29117,14 +29248,14 @@ class OnTriggerParser {
29117
29248
  }
29118
29249
  // If we hit a comma outside of a comma-delimited syntax, it means
29119
29250
  // that we're at the top level and we're starting a new parameter.
29120
- if (commaDelimStack.length === 0 && token.isCharacter($COMMA) && current.length > 0) {
29121
- parameters.push(current);
29122
- current = '';
29251
+ if (commaDelimStack.length === 0 && token.isCharacter($COMMA) && tokens.length > 0) {
29252
+ parameters.push({ expression: this.tokenRangeText(tokens), start: tokens[0].index });
29123
29253
  this.advance();
29254
+ tokens = [];
29124
29255
  continue;
29125
29256
  }
29126
29257
  // Otherwise treat the token as a plain text character in the current parameter.
29127
- current += this.tokenText();
29258
+ tokens.push(token);
29128
29259
  this.advance();
29129
29260
  }
29130
29261
  if (!this.token().isCharacter($RPAREN) || commaDelimStack.length > 0) {
@@ -29136,10 +29267,11 @@ class OnTriggerParser {
29136
29267
  }
29137
29268
  return parameters;
29138
29269
  }
29139
- tokenText() {
29140
- // Tokens have a toString already which we could use, but for string tokens it omits the quotes.
29141
- // Eventually we could expose this information on the token directly.
29142
- return this.expression.slice(this.start + this.token().index, this.start + this.token().end);
29270
+ tokenRangeText(tokens) {
29271
+ if (tokens.length === 0) {
29272
+ return '';
29273
+ }
29274
+ return this.expression.slice(this.start + tokens[0].index, this.start + tokens[tokens.length - 1].end);
29143
29275
  }
29144
29276
  trackTrigger(name, trigger) {
29145
29277
  trackTrigger(name, this.triggers, this.errors, trigger);
@@ -29172,7 +29304,7 @@ function createTimerTrigger(parameters, nameSpan, sourceSpan, prefetchSpan, onSo
29172
29304
  if (parameters.length !== 1) {
29173
29305
  throw new Error(`"${OnTriggerType.TIMER}" trigger must have exactly one parameter`);
29174
29306
  }
29175
- const delay = parseDeferredTime(parameters[0]);
29307
+ const delay = parseDeferredTime(parameters[0].expression);
29176
29308
  if (delay === null) {
29177
29309
  throw new Error(`Could not parse time value of trigger "${OnTriggerType.TIMER}"`);
29178
29310
  }
@@ -29184,17 +29316,61 @@ function createImmediateTrigger(parameters, nameSpan, sourceSpan, prefetchSpan,
29184
29316
  }
29185
29317
  return new ImmediateDeferredTrigger(nameSpan, sourceSpan, prefetchSpan, onSourceSpan, hydrateSpan);
29186
29318
  }
29187
- function createHoverTrigger(parameters, nameSpan, sourceSpan, prefetchSpan, onSourceSpan, hydrateSpan, placeholder, validator) {
29319
+ function createHoverTrigger(parameters, nameSpan, sourceSpan, prefetchSpan, onSourceSpan, hydrateSpan, validator) {
29188
29320
  validator(OnTriggerType.HOVER, parameters);
29189
- return new HoverDeferredTrigger(parameters[0] ?? null, nameSpan, sourceSpan, prefetchSpan, onSourceSpan, hydrateSpan);
29321
+ return new HoverDeferredTrigger(parameters[0]?.expression ?? null, nameSpan, sourceSpan, prefetchSpan, onSourceSpan, hydrateSpan);
29190
29322
  }
29191
29323
  function createInteractionTrigger(parameters, nameSpan, sourceSpan, prefetchSpan, onSourceSpan, hydrateSpan, validator) {
29192
29324
  validator(OnTriggerType.INTERACTION, parameters);
29193
- return new InteractionDeferredTrigger(parameters[0] ?? null, nameSpan, sourceSpan, prefetchSpan, onSourceSpan, hydrateSpan);
29325
+ return new InteractionDeferredTrigger(parameters[0]?.expression ?? null, nameSpan, sourceSpan, prefetchSpan, onSourceSpan, hydrateSpan);
29194
29326
  }
29195
- function createViewportTrigger(parameters, nameSpan, sourceSpan, prefetchSpan, onSourceSpan, hydrateSpan, validator) {
29327
+ function createViewportTrigger(start, isHydrationTrigger, bindingParser, parameters, nameSpan, sourceSpan, prefetchSpan, onSourceSpan, hydrateSpan, validator) {
29196
29328
  validator(OnTriggerType.VIEWPORT, parameters);
29197
- return new ViewportDeferredTrigger(parameters[0] ?? null, nameSpan, sourceSpan, prefetchSpan, onSourceSpan, hydrateSpan);
29329
+ let reference;
29330
+ let options;
29331
+ if (parameters.length === 0) {
29332
+ reference = options = null;
29333
+ }
29334
+ else if (!parameters[0].expression.startsWith('{')) {
29335
+ reference = parameters[0].expression;
29336
+ options = null;
29337
+ }
29338
+ else {
29339
+ const parsed = bindingParser.parseBinding(parameters[0].expression, false, sourceSpan, sourceSpan.start.offset + start + parameters[0].start);
29340
+ if (!(parsed.ast instanceof LiteralMap)) {
29341
+ throw new Error('Options parameter of the "viewport" trigger must be an object literal');
29342
+ }
29343
+ else if (parsed.ast.keys.some((key) => key.key === 'root')) {
29344
+ throw new Error('The "root" option is not supported in the options parameter of the "viewport" trigger');
29345
+ }
29346
+ const triggerIndex = parsed.ast.keys.findIndex((key) => key.key === 'trigger');
29347
+ if (triggerIndex === -1) {
29348
+ reference = null;
29349
+ options = parsed.ast;
29350
+ }
29351
+ else {
29352
+ const value = parsed.ast.values[triggerIndex];
29353
+ const triggerFilter = (_, index) => index !== triggerIndex;
29354
+ if (!(value instanceof PropertyRead) ||
29355
+ !(value.receiver instanceof ImplicitReceiver) ||
29356
+ value.receiver instanceof ThisReceiver) {
29357
+ throw new Error(`"trigger" option of the "viewport" trigger must be an identifier`);
29358
+ }
29359
+ reference = value.name;
29360
+ options = new LiteralMap(parsed.ast.span, parsed.ast.sourceSpan, parsed.ast.keys.filter(triggerFilter), parsed.ast.values.filter(triggerFilter));
29361
+ }
29362
+ }
29363
+ if (isHydrationTrigger && reference !== null) {
29364
+ throw new Error(`"viewport" hydration trigger cannot have a "trigger"`);
29365
+ }
29366
+ else if (options) {
29367
+ const dynamicNode = DynamicAstValidator.findDynamicNode(options);
29368
+ if (dynamicNode !== null) {
29369
+ throw new Error(`Options of the "viewport" trigger must be an object ` +
29370
+ `literal containing only literal values, but "${dynamicNode.constructor.name}" was found`);
29371
+ }
29372
+ }
29373
+ return new ViewportDeferredTrigger(reference, options, nameSpan, sourceSpan, prefetchSpan, onSourceSpan, hydrateSpan);
29198
29374
  }
29199
29375
  /**
29200
29376
  * Checks whether the structure of a non-hydrate reference-based trigger is valid.
@@ -29212,6 +29388,12 @@ function validatePlainReferenceBasedTrigger(type, parameters) {
29212
29388
  * @param parameters Parameters of the trigger.
29213
29389
  */
29214
29390
  function validateHydrateReferenceBasedTrigger(type, parameters) {
29391
+ if (type === OnTriggerType.VIEWPORT) {
29392
+ if (parameters.length > 1) {
29393
+ throw new Error(`Hydration trigger "${type}" cannot have more than one parameter`);
29394
+ }
29395
+ return;
29396
+ }
29215
29397
  if (parameters.length > 0) {
29216
29398
  throw new Error(`Hydration trigger "${type}" cannot have parameters`);
29217
29399
  }
@@ -29241,6 +29423,25 @@ function parseDeferredTime(value) {
29241
29423
  const [time, units] = match;
29242
29424
  return parseFloat(time) * (units === 's' ? 1000 : 1);
29243
29425
  }
29426
+ class DynamicAstValidator extends RecursiveAstVisitor {
29427
+ dynamicNode = null;
29428
+ static findDynamicNode(ast) {
29429
+ const visitor = new DynamicAstValidator();
29430
+ visitor.visit(ast);
29431
+ return visitor.dynamicNode;
29432
+ }
29433
+ visit(ast) {
29434
+ if (!(ast instanceof ASTWithSource) &&
29435
+ !(ast instanceof LiteralPrimitive) &&
29436
+ !(ast instanceof LiteralArray) &&
29437
+ !(ast instanceof LiteralMap)) {
29438
+ this.dynamicNode = ast;
29439
+ }
29440
+ else {
29441
+ super.visit(ast);
29442
+ }
29443
+ }
29444
+ }
29244
29445
 
29245
29446
  /** Pattern to identify a `prefetch when` trigger. */
29246
29447
  const PREFETCH_WHEN_PATTERN = /^prefetch\s+when\s/;
@@ -29271,7 +29472,7 @@ function isConnectedDeferLoopBlock(name) {
29271
29472
  function createDeferredBlock(ast, connectedBlocks, visitor, bindingParser) {
29272
29473
  const errors = [];
29273
29474
  const { placeholder, loading, error } = parseConnectedBlocks(connectedBlocks, errors, visitor);
29274
- const { triggers, prefetchTriggers, hydrateTriggers } = parsePrimaryTriggers(ast, bindingParser, errors, placeholder);
29475
+ const { triggers, prefetchTriggers, hydrateTriggers } = parsePrimaryTriggers(ast, bindingParser, errors);
29275
29476
  // The `defer` block has a main span encompassing all of the connected branches as well.
29276
29477
  let lastEndSourceSpan = ast.endSourceSpan;
29277
29478
  let endOfLastSourceSpan = ast.sourceSpan.end;
@@ -29393,19 +29594,19 @@ function parsePrimaryTriggers(ast, bindingParser, errors, placeholder) {
29393
29594
  parseWhenTrigger(param, bindingParser, triggers, errors);
29394
29595
  }
29395
29596
  else if (ON_PARAMETER_PATTERN.test(param.expression)) {
29396
- parseOnTrigger(param, triggers, errors, placeholder);
29597
+ parseOnTrigger(param, bindingParser, triggers, errors);
29397
29598
  }
29398
29599
  else if (PREFETCH_WHEN_PATTERN.test(param.expression)) {
29399
29600
  parseWhenTrigger(param, bindingParser, prefetchTriggers, errors);
29400
29601
  }
29401
29602
  else if (PREFETCH_ON_PATTERN.test(param.expression)) {
29402
- parseOnTrigger(param, prefetchTriggers, errors, placeholder);
29603
+ parseOnTrigger(param, bindingParser, prefetchTriggers, errors);
29403
29604
  }
29404
29605
  else if (HYDRATE_WHEN_PATTERN.test(param.expression)) {
29405
29606
  parseWhenTrigger(param, bindingParser, hydrateTriggers, errors);
29406
29607
  }
29407
29608
  else if (HYDRATE_ON_PATTERN.test(param.expression)) {
29408
- parseOnTrigger(param, hydrateTriggers, errors, placeholder);
29609
+ parseOnTrigger(param, bindingParser, hydrateTriggers, errors);
29409
29610
  }
29410
29611
  else if (HYDRATE_NEVER_PATTERN.test(param.expression)) {
29411
29612
  parseNeverTrigger(param, hydrateTriggers, errors);
@@ -30360,7 +30561,7 @@ function compileComponentFromMetadata(meta, constantPool, bindingParser) {
30360
30561
  : TemplateCompilationMode.Full;
30361
30562
  // First the template is ingested into IR:
30362
30563
  const tpl = ingestComponent(meta.name, meta.template.nodes, constantPool, compilationMode, meta.relativeContextFilePath, meta.i18nUseExternalIds, meta.defer, allDeferrableDepsFn, meta.relativeTemplatePath, getTemplateSourceLocationsEnabled());
30363
- // Then the IR is transformed to prepare it for cod egeneration.
30564
+ // Then the IR is transformed to prepare it for code generation.
30364
30565
  transform(tpl, CompilationJobKind.Tmpl);
30365
30566
  // Finally we emit the template function:
30366
30567
  const templateFn = emitTemplateFn(tpl, constantPool);
@@ -30815,6 +31016,9 @@ class CombinedRecursiveAstVisitor extends RecursiveAstVisitor {
30815
31016
  if (trigger instanceof BoundDeferredTrigger) {
30816
31017
  this.visit(trigger.value);
30817
31018
  }
31019
+ else if (trigger instanceof ViewportDeferredTrigger && trigger.options !== null) {
31020
+ this.visit(trigger.options);
31021
+ }
30818
31022
  }
30819
31023
  visitDeferredBlockPlaceholder(block) {
30820
31024
  this.visitAllTemplateNodes(block.children);
@@ -32909,7 +33113,7 @@ function isAttrNode(ast) {
32909
33113
  * @description
32910
33114
  * Entry point for all public APIs of the compiler package.
32911
33115
  */
32912
- const VERSION = new Version('21.0.0-next.6');
33116
+ const VERSION = new Version('21.0.0-next.8');
32913
33117
 
32914
33118
  //////////////////////////////////////
32915
33119
  // THIS FILE HAS GLOBAL SIDE EFFECT //
@@ -33285,6 +33489,12 @@ exports.ErrorCode = void 0;
33285
33489
  * ```
33286
33490
  */
33287
33491
  ErrorCode[ErrorCode["DEFER_IMPLICIT_TRIGGER_INVALID_PLACEHOLDER"] = 8020] = "DEFER_IMPLICIT_TRIGGER_INVALID_PLACEHOLDER";
33492
+ /**
33493
+ * Raised when an `@defer` block defines unreachable or redundant triggers.
33494
+ * Examples: multiple main triggers, 'on immediate' together with other mains or any prefetch,
33495
+ * prefetch timer delay that is not earlier than the main timer, or an identical prefetch
33496
+ */
33497
+ ErrorCode[ErrorCode["DEFER_TRIGGER_MISCONFIGURATION"] = 8021] = "DEFER_TRIGGER_MISCONFIGURATION";
33288
33498
  /**
33289
33499
  * A two way binding in a template has an incorrect syntax,
33290
33500
  * parentheses outside brackets. For example:
@@ -33646,6 +33856,7 @@ exports.ExtendedTemplateDiagnosticName = void 0;
33646
33856
  ExtendedTemplateDiagnosticName["UNUSED_STANDALONE_IMPORTS"] = "unusedStandaloneImports";
33647
33857
  ExtendedTemplateDiagnosticName["UNPARENTHESIZED_NULLISH_COALESCING"] = "unparenthesizedNullishCoalescing";
33648
33858
  ExtendedTemplateDiagnosticName["UNINVOKED_FUNCTION_IN_TEXT_INTERPOLATION"] = "uninvokedFunctionInTextInterpolation";
33859
+ ExtendedTemplateDiagnosticName["DEFER_TRIGGER_MISCONFIGURATION"] = "deferTriggerMisconfiguration";
33649
33860
  })(exports.ExtendedTemplateDiagnosticName || (exports.ExtendedTemplateDiagnosticName = {}));
33650
33861
 
33651
33862
  /**
@@ -33972,7 +34183,7 @@ class NodeJSPathManipulation {
33972
34183
  // G3-ESM-MARKER: G3 uses CommonJS, but externally everything in ESM.
33973
34184
  // CommonJS/ESM interop for determining the current file name and containing dir.
33974
34185
  const isCommonJS = typeof __filename !== 'undefined';
33975
- const currentFileUrl = isCommonJS ? null : (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('project_tsconfig_paths-sFatqIE5.cjs', document.baseURI).href));
34186
+ const currentFileUrl = isCommonJS ? null : (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('project_tsconfig_paths-CdhVNYMk.cjs', document.baseURI).href));
33976
34187
  // Note, when this code loads in the browser, `url` may be an empty `{}` due to the Closure shims.
33977
34188
  const currentFileName = isCommonJS
33978
34189
  ? __filename
@@ -40375,6 +40586,120 @@ function parseFieldStringArrayValue(directive, field, evaluator) {
40375
40586
  }
40376
40587
  return value;
40377
40588
  }
40589
+ /**
40590
+ * Returns a function that can be used to extract data for the `setClassMetadata`
40591
+ * calls from undecorated directive class members.
40592
+ */
40593
+ function getDirectiveUndecoratedMetadataExtractor(reflector, importTracker) {
40594
+ return (member) => {
40595
+ const input = tryParseSignalInputMapping(member, reflector, importTracker);
40596
+ if (input !== null) {
40597
+ return getDecoratorMetaArray([
40598
+ [new ExternalExpr(Identifiers.inputDecorator), memberMetadataFromSignalInput(input)],
40599
+ ]);
40600
+ }
40601
+ const output = tryParseInitializerBasedOutput(member, reflector, importTracker);
40602
+ if (output !== null) {
40603
+ return getDecoratorMetaArray([
40604
+ [
40605
+ new ExternalExpr(Identifiers.outputDecorator),
40606
+ memberMetadataFromInitializerOutput(output.metadata),
40607
+ ],
40608
+ ]);
40609
+ }
40610
+ const model = tryParseSignalModelMapping(member, reflector, importTracker);
40611
+ if (model !== null) {
40612
+ return getDecoratorMetaArray([
40613
+ [
40614
+ new ExternalExpr(Identifiers.inputDecorator),
40615
+ memberMetadataFromSignalInput(model.input),
40616
+ ],
40617
+ [
40618
+ new ExternalExpr(Identifiers.outputDecorator),
40619
+ memberMetadataFromInitializerOutput(model.output),
40620
+ ],
40621
+ ]);
40622
+ }
40623
+ const query = tryParseSignalQueryFromInitializer(member, reflector, importTracker);
40624
+ if (query !== null) {
40625
+ let identifier;
40626
+ if (query.name === 'viewChild') {
40627
+ identifier = Identifiers.viewChildDecorator;
40628
+ }
40629
+ else if (query.name === 'viewChildren') {
40630
+ identifier = Identifiers.viewChildrenDecorator;
40631
+ }
40632
+ else if (query.name === 'contentChild') {
40633
+ identifier = Identifiers.contentChildDecorator;
40634
+ }
40635
+ else if (query.name === 'contentChildren') {
40636
+ identifier = Identifiers.contentChildrenDecorator;
40637
+ }
40638
+ else {
40639
+ return null;
40640
+ }
40641
+ return getDecoratorMetaArray([
40642
+ [new ExternalExpr(identifier), memberMetadataFromSignalQuery(query.call)],
40643
+ ]);
40644
+ }
40645
+ return null;
40646
+ };
40647
+ }
40648
+ function getDecoratorMetaArray(decorators) {
40649
+ return new LiteralArrayExpr(decorators.map(([type, args]) => literalMap([
40650
+ { key: 'type', value: type, quoted: false },
40651
+ { key: 'args', value: args, quoted: false },
40652
+ ])));
40653
+ }
40654
+ function memberMetadataFromSignalInput(input) {
40655
+ // Note that for signal inputs the transform is captured in the signal
40656
+ // initializer so we don't need to capture it here.
40657
+ return new LiteralArrayExpr([
40658
+ literalMap([
40659
+ {
40660
+ key: 'isSignal',
40661
+ value: literal(true),
40662
+ quoted: false,
40663
+ },
40664
+ {
40665
+ key: 'alias',
40666
+ value: literal(input.bindingPropertyName),
40667
+ quoted: false,
40668
+ },
40669
+ {
40670
+ key: 'required',
40671
+ value: literal(input.required),
40672
+ quoted: false,
40673
+ },
40674
+ ]),
40675
+ ]);
40676
+ }
40677
+ function memberMetadataFromInitializerOutput(output) {
40678
+ return new LiteralArrayExpr([literal(output.bindingPropertyName)]);
40679
+ }
40680
+ function memberMetadataFromSignalQuery(call) {
40681
+ const firstArg = call.arguments[0];
40682
+ const firstArgMeta = ts.isStringLiteralLike(firstArg) || ts.isCallExpression(firstArg)
40683
+ ? new WrappedNodeExpr(firstArg)
40684
+ : // If the first argument is a class reference, we need to wrap it in a `forwardRef`
40685
+ // because the reference might occur after the current class. This wouldn't be flagged
40686
+ // on the query initializer, because it executes after the class is initialized, whereas
40687
+ // `setClassMetadata` runs immediately.
40688
+ new ExternalExpr(Identifiers.forwardRef).callFn([
40689
+ new ArrowFunctionExpr([], new WrappedNodeExpr(firstArg)),
40690
+ ]);
40691
+ const entries = [
40692
+ // We use wrapped nodes here, because the output AST doesn't support spread assignments.
40693
+ firstArgMeta,
40694
+ new WrappedNodeExpr(ts.factory.createObjectLiteralExpression([
40695
+ ...(call.arguments.length > 1
40696
+ ? [ts.factory.createSpreadAssignment(call.arguments[1])]
40697
+ : []),
40698
+ ts.factory.createPropertyAssignment('isSignal', ts.factory.createTrue()),
40699
+ ])),
40700
+ ];
40701
+ return new LiteralArrayExpr(entries);
40702
+ }
40378
40703
  function isStringArrayOrDie(value, name, node) {
40379
40704
  if (!Array.isArray(value)) {
40380
40705
  return false;
@@ -44695,10 +45020,10 @@ class OutOfBandDiagnosticRecorderImpl {
44695
45020
  this._diagnostics.push(makeTemplateDiagnostic(id, this.resolver.getTemplateSourceMapping(id), node.keySpan || node.sourceSpan, ts.DiagnosticCategory.Error, ngErrorCode(exports.ErrorCode.UNCLAIMED_DIRECTIVE_BINDING), errorMsg));
44696
45021
  }
44697
45022
  deferImplicitTriggerMissingPlaceholder(id, trigger) {
44698
- this._diagnostics.push(makeTemplateDiagnostic(id, this.resolver.getTemplateSourceMapping(id), trigger.sourceSpan, ts.DiagnosticCategory.Error, ngErrorCode(exports.ErrorCode.DEFER_IMPLICIT_TRIGGER_MISSING_PLACEHOLDER), 'Trigger with no parameters can only be placed on an @defer that has a @placeholder block'));
45023
+ this._diagnostics.push(makeTemplateDiagnostic(id, this.resolver.getTemplateSourceMapping(id), trigger.sourceSpan, ts.DiagnosticCategory.Error, ngErrorCode(exports.ErrorCode.DEFER_IMPLICIT_TRIGGER_MISSING_PLACEHOLDER), 'Trigger with no target can only be placed on an @defer that has a @placeholder block'));
44699
45024
  }
44700
45025
  deferImplicitTriggerInvalidPlaceholder(id, trigger) {
44701
- this._diagnostics.push(makeTemplateDiagnostic(id, this.resolver.getTemplateSourceMapping(id), trigger.sourceSpan, ts.DiagnosticCategory.Error, ngErrorCode(exports.ErrorCode.DEFER_IMPLICIT_TRIGGER_INVALID_PLACEHOLDER), 'Trigger with no parameters can only be placed on an @defer that has a ' +
45026
+ this._diagnostics.push(makeTemplateDiagnostic(id, this.resolver.getTemplateSourceMapping(id), trigger.sourceSpan, ts.DiagnosticCategory.Error, ngErrorCode(exports.ErrorCode.DEFER_IMPLICIT_TRIGGER_INVALID_PLACEHOLDER), 'Trigger with no target can only be placed on an @defer that has a ' +
44702
45027
  '@placeholder block with exactly one root element node'));
44703
45028
  }
44704
45029
  }
@@ -46916,6 +47241,28 @@ class TcbForOfOp extends TcbOp {
46916
47241
  return null;
46917
47242
  }
46918
47243
  }
47244
+ /**
47245
+ * A `TcbOp` which can be used to type check the options of an `IntersectionObserver`.
47246
+ */
47247
+ class TcbIntersectionObserverOp extends TcbOp {
47248
+ tcb;
47249
+ scope;
47250
+ options;
47251
+ constructor(tcb, scope, options) {
47252
+ super();
47253
+ this.tcb = tcb;
47254
+ this.scope = scope;
47255
+ this.options = options;
47256
+ }
47257
+ optional = false;
47258
+ execute() {
47259
+ const options = tcbExpression(this.options, this.tcb, this.scope);
47260
+ const callback = ts.factory.createNonNullExpression(ts.factory.createNull());
47261
+ const expression = ts.factory.createNewExpression(ts.factory.createIdentifier('IntersectionObserver'), undefined, [callback, options]);
47262
+ this.scope.addStatement(ts.factory.createExpressionStatement(expression));
47263
+ return null;
47264
+ }
47265
+ }
46919
47266
  /**
46920
47267
  * Overall generation context for the type check block.
46921
47268
  *
@@ -47687,6 +48034,9 @@ class Scope {
47687
48034
  if (triggers.when !== undefined) {
47688
48035
  this.opQueue.push(new TcbExpressionOp(this.tcb, this, triggers.when.value));
47689
48036
  }
48037
+ if (triggers.viewport !== undefined && triggers.viewport.options !== null) {
48038
+ this.opQueue.push(new TcbIntersectionObserverOp(this.tcb, this, triggers.viewport.options));
48039
+ }
47690
48040
  if (triggers.hover !== undefined) {
47691
48041
  this.validateReferenceBasedDeferredTrigger(block, triggers.hover);
47692
48042
  }
@@ -49657,6 +50007,9 @@ class TemplateTypeCheckerImpl {
49657
50007
  const { data } = this.getLatestComponentState(directive, optimizeFor);
49658
50008
  return data?.hostElement ?? null;
49659
50009
  }
50010
+ getDirectivesOfNode(component, node) {
50011
+ return (this.getLatestComponentState(component).data?.boundTarget.getDirectivesOfNode(node) ?? null);
50012
+ }
49660
50013
  getUsedDirectives(component) {
49661
50014
  return this.getLatestComponentState(component).data?.boundTarget.getUsedDirectives() ?? null;
49662
50015
  }
@@ -50992,6 +51345,7 @@ exports.Declaration = Declaration;
50992
51345
  exports.DeclareFunctionStmt = DeclareFunctionStmt;
50993
51346
  exports.DeclareVarStmt = DeclareVarStmt;
50994
51347
  exports.DefaultImportTracker = DefaultImportTracker;
51348
+ exports.DeferredBlock = DeferredBlock;
50995
51349
  exports.DefinitionMap = DefinitionMap;
50996
51350
  exports.Directive = Directive$1;
50997
51351
  exports.DomElementSchemaRegistry = DomElementSchemaRegistry;
@@ -51006,14 +51360,17 @@ exports.FatalDiagnosticError = FatalDiagnosticError;
51006
51360
  exports.FnParam = FnParam;
51007
51361
  exports.ForLoopBlock = ForLoopBlock;
51008
51362
  exports.FunctionExpr = FunctionExpr;
51363
+ exports.HoverDeferredTrigger = HoverDeferredTrigger;
51009
51364
  exports.HtmlParser = HtmlParser;
51010
51365
  exports.INPUT_INITIALIZER_FN = INPUT_INITIALIZER_FN;
51011
51366
  exports.Icu = Icu;
51012
51367
  exports.IcuPlaceholder = IcuPlaceholder;
51013
51368
  exports.Identifiers = Identifiers;
51014
51369
  exports.IfBlock = IfBlock;
51370
+ exports.ImmediateDeferredTrigger = ImmediateDeferredTrigger;
51015
51371
  exports.ImplicitReceiver = ImplicitReceiver;
51016
51372
  exports.ImportManager = ImportManager;
51373
+ exports.InteractionDeferredTrigger = InteractionDeferredTrigger;
51017
51374
  exports.Interpolation = Interpolation$1;
51018
51375
  exports.InvokeFunctionExpr = InvokeFunctionExpr;
51019
51376
  exports.KeyedRead = KeyedRead;
@@ -51068,6 +51425,7 @@ exports.Text$1 = Text$1;
51068
51425
  exports.Text$2 = Text$2;
51069
51426
  exports.TextAttribute = TextAttribute;
51070
51427
  exports.ThisReceiver = ThisReceiver;
51428
+ exports.TimerDeferredTrigger = TimerDeferredTrigger;
51071
51429
  exports.Trait = Trait;
51072
51430
  exports.TypeCheckShimGenerator = TypeCheckShimGenerator;
51073
51431
  exports.TypeScriptReflectionHost = TypeScriptReflectionHost;
@@ -51075,6 +51433,7 @@ exports.UNSAFE_OBJECT_KEY_NAME_REGEXP = UNSAFE_OBJECT_KEY_NAME_REGEXP;
51075
51433
  exports.UnifiedModulesStrategy = UnifiedModulesStrategy;
51076
51434
  exports.Variable = Variable;
51077
51435
  exports.Version = Version;
51436
+ exports.ViewportDeferredTrigger = ViewportDeferredTrigger;
51078
51437
  exports.WhitespaceVisitor = WhitespaceVisitor;
51079
51438
  exports.WrappedNodeExpr = WrappedNodeExpr;
51080
51439
  exports.Xmb = Xmb;
@@ -51130,6 +51489,7 @@ exports.getConstructorDependencies = getConstructorDependencies;
51130
51489
  exports.getContainingImportDeclaration = getContainingImportDeclaration;
51131
51490
  exports.getDefaultImportDeclaration = getDefaultImportDeclaration;
51132
51491
  exports.getDirectiveDiagnostics = getDirectiveDiagnostics;
51492
+ exports.getDirectiveUndecoratedMetadataExtractor = getDirectiveUndecoratedMetadataExtractor;
51133
51493
  exports.getFileSystem = getFileSystem;
51134
51494
  exports.getOriginNodeForDiagnostics = getOriginNodeForDiagnostics;
51135
51495
  exports.getProjectTsConfigPaths = getProjectTsConfigPaths;