@angular/core 17.2.0-next.1 → 17.2.0-rc.1

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 (85) hide show
  1. package/esm2022/primitives/signals/index.mjs +3 -3
  2. package/esm2022/src/application/application_ngmodule_factory_compiler.mjs +61 -0
  3. package/esm2022/src/application/application_ref.mjs +55 -69
  4. package/esm2022/src/authoring/input/input.mjs +48 -0
  5. package/esm2022/src/authoring/input/input_signal.mjs +40 -0
  6. package/esm2022/src/authoring/input/input_signal_node.mjs +22 -0
  7. package/esm2022/src/authoring/input/input_type_checking.mjs +9 -0
  8. package/esm2022/src/authoring/model/model.mjs +50 -0
  9. package/esm2022/src/authoring/model/model_signal.mjs +68 -0
  10. package/esm2022/src/authoring/model/model_signal_node.mjs +21 -0
  11. package/esm2022/src/authoring/output.mjs +33 -0
  12. package/esm2022/src/authoring/queries.mjs +1 -1
  13. package/esm2022/src/authoring.mjs +3 -2
  14. package/esm2022/src/core.mjs +7 -5
  15. package/esm2022/src/core_reactivity_export_internal.mjs +2 -2
  16. package/esm2022/src/core_render3_private_export.mjs +5 -4
  17. package/esm2022/src/defer/instructions.mjs +13 -6
  18. package/esm2022/src/di/create_injector.mjs +1 -1
  19. package/esm2022/src/di/injector_compatibility.mjs +1 -1
  20. package/esm2022/src/di/injector_token.mjs +1 -1
  21. package/esm2022/src/di/null_injector.mjs +1 -1
  22. package/esm2022/src/di/r3_injector.mjs +1 -1
  23. package/esm2022/src/errors.mjs +1 -1
  24. package/esm2022/src/hydration/utils.mjs +1 -1
  25. package/esm2022/src/platform/platform_ref.mjs +3 -2
  26. package/esm2022/src/render3/after_render_hooks.mjs +2 -6
  27. package/esm2022/src/render3/apply_value_input_field.mjs +1 -1
  28. package/esm2022/src/render3/component_ref.mjs +2 -2
  29. package/esm2022/src/render3/definition.mjs +2 -2
  30. package/esm2022/src/render3/di.mjs +1 -1
  31. package/esm2022/src/render3/errors_di.mjs +2 -2
  32. package/esm2022/src/render3/features/ng_onchanges_feature.mjs +1 -1
  33. package/esm2022/src/render3/i18n/i18n_locale_id.mjs +2 -2
  34. package/esm2022/src/render3/index.mjs +2 -2
  35. package/esm2022/src/render3/instructions/all.mjs +2 -1
  36. package/esm2022/src/render3/instructions/change_detection.mjs +6 -6
  37. package/esm2022/src/render3/instructions/listener.mjs +13 -4
  38. package/esm2022/src/render3/instructions/queries.mjs +3 -5
  39. package/esm2022/src/render3/instructions/queries_signals.mjs +4 -5
  40. package/esm2022/src/render3/instructions/render.mjs +5 -2
  41. package/esm2022/src/render3/instructions/shared.mjs +2 -2
  42. package/esm2022/src/render3/instructions/styling.mjs +1 -1
  43. package/esm2022/src/render3/instructions/two_way.mjs +70 -0
  44. package/esm2022/src/render3/instructions/write_to_directive_input.mjs +2 -2
  45. package/esm2022/src/render3/interfaces/attribute_marker.mjs +9 -0
  46. package/esm2022/src/render3/interfaces/definition.mjs +2 -8
  47. package/esm2022/src/render3/interfaces/input_flags.mjs +15 -0
  48. package/esm2022/src/render3/interfaces/node.mjs +1 -1
  49. package/esm2022/src/render3/interfaces/query.mjs +1 -1
  50. package/esm2022/src/render3/interfaces/view.mjs +1 -1
  51. package/esm2022/src/render3/jit/environment.mjs +5 -2
  52. package/esm2022/src/render3/node_selector_matcher.mjs +1 -1
  53. package/esm2022/src/render3/query.mjs +17 -3
  54. package/esm2022/src/render3/query_reactive.mjs +51 -75
  55. package/esm2022/src/render3/reactivity/signal.mjs +21 -1
  56. package/esm2022/src/render3/styling/static_styling.mjs +1 -1
  57. package/esm2022/src/render3/util/attrs_utils.mjs +1 -1
  58. package/esm2022/src/render3/util/discovery_utils.mjs +1 -1
  59. package/esm2022/src/render3/util/view_utils.mjs +3 -3
  60. package/esm2022/src/render3/view_ref.mjs +1 -1
  61. package/esm2022/src/util/stringify.mjs +2 -2
  62. package/esm2022/src/version.mjs +1 -1
  63. package/esm2022/testing/src/component_fixture.mjs +4 -4
  64. package/esm2022/testing/src/logger.mjs +3 -3
  65. package/fesm2022/core.mjs +14568 -14203
  66. package/fesm2022/core.mjs.map +1 -1
  67. package/fesm2022/primitives/signals.mjs +1 -1
  68. package/fesm2022/rxjs-interop.mjs +1 -1
  69. package/fesm2022/testing.mjs +4 -4
  70. package/fesm2022/testing.mjs.map +1 -1
  71. package/index.d.ts +366 -11
  72. package/package.json +1 -1
  73. package/primitives/signals/index.d.ts +2 -2
  74. package/rxjs-interop/index.d.ts +1 -1
  75. package/schematics/migrations/block-template-entities/bundle.js +413 -91
  76. package/schematics/migrations/block-template-entities/bundle.js.map +4 -4
  77. package/schematics/ng-generate/control-flow-migration/bundle.js +413 -91
  78. package/schematics/ng-generate/control-flow-migration/bundle.js.map +4 -4
  79. package/schematics/ng-generate/standalone-migration/bundle.js +6087 -5623
  80. package/schematics/ng-generate/standalone-migration/bundle.js.map +4 -4
  81. package/testing/index.d.ts +1 -1
  82. package/esm2022/src/authoring/input.mjs +0 -48
  83. package/esm2022/src/authoring/input_signal.mjs +0 -40
  84. package/esm2022/src/authoring/input_signal_node.mjs +0 -22
  85. package/esm2022/src/authoring/input_type_checking.mjs +0 -9
@@ -1752,6 +1752,7 @@ var ConstantPool = class {
1752
1752
  this.literals = /* @__PURE__ */ new Map();
1753
1753
  this.literalFactories = /* @__PURE__ */ new Map();
1754
1754
  this.sharedConstants = /* @__PURE__ */ new Map();
1755
+ this._claimedNames = /* @__PURE__ */ new Map();
1755
1756
  this.nextNameIndex = 0;
1756
1757
  }
1757
1758
  getConstLiteral(literal2, forceShared) {
@@ -1844,8 +1845,12 @@ var ConstantPool = class {
1844
1845
  }
1845
1846
  return { literalFactory, literalFactoryArguments };
1846
1847
  }
1847
- uniqueName(prefix) {
1848
- return `${prefix}${this.nextNameIndex++}`;
1848
+ uniqueName(name, alwaysIncludeSuffix = true) {
1849
+ var _a2;
1850
+ const count = (_a2 = this._claimedNames.get(name)) != null ? _a2 : 0;
1851
+ const result = count === 0 && !alwaysIncludeSuffix ? `${name}` : `${name}${count}`;
1852
+ this._claimedNames.set(name, count + 1);
1853
+ return result;
1849
1854
  }
1850
1855
  freshName() {
1851
1856
  return this.uniqueName(CONSTANT_PREFIX);
@@ -2479,6 +2484,15 @@ var Identifiers = _Identifiers;
2479
2484
  (() => {
2480
2485
  _Identifiers.queryAdvance = { name: "\u0275\u0275queryAdvance", moduleName: CORE };
2481
2486
  })();
2487
+ (() => {
2488
+ _Identifiers.twoWayProperty = { name: "\u0275\u0275twoWayProperty", moduleName: CORE };
2489
+ })();
2490
+ (() => {
2491
+ _Identifiers.twoWayBindingSet = { name: "\u0275\u0275twoWayBindingSet", moduleName: CORE };
2492
+ })();
2493
+ (() => {
2494
+ _Identifiers.twoWayListener = { name: "\u0275\u0275twoWayListener", moduleName: CORE };
2495
+ })();
2482
2496
  (() => {
2483
2497
  _Identifiers.NgOnChangesFeature = { name: "\u0275\u0275NgOnChangesFeature", moduleName: CORE };
2484
2498
  })();
@@ -2548,6 +2562,9 @@ var Identifiers = _Identifiers;
2548
2562
  (() => {
2549
2563
  _Identifiers.UnwrapDirectiveSignalInputs = { name: "\u0275UnwrapDirectiveSignalInputs", moduleName: CORE };
2550
2564
  })();
2565
+ (() => {
2566
+ _Identifiers.unwrapWritableSignal = { name: "\u0275unwrapWritableSignal", moduleName: CORE };
2567
+ })();
2551
2568
 
2552
2569
  // bazel-out/k8-fastbuild/bin/packages/compiler/src/util.mjs
2553
2570
  var DASH_CASE_REGEXP = /-+([a-z0-9])/g;
@@ -4219,7 +4236,9 @@ var CHAINABLE_INSTRUCTIONS = /* @__PURE__ */ new Set([
4219
4236
  Identifiers.textInterpolate7,
4220
4237
  Identifiers.textInterpolate8,
4221
4238
  Identifiers.textInterpolateV,
4222
- Identifiers.templateCreate
4239
+ Identifiers.templateCreate,
4240
+ Identifiers.twoWayProperty,
4241
+ Identifiers.twoWayListener
4223
4242
  ]);
4224
4243
  function invokeInstruction(span, reference2, params) {
4225
4244
  return importExpr(reference2, null, span).callFn(params, span);
@@ -5852,30 +5871,10 @@ var EventHandlerVars = _EventHandlerVars;
5852
5871
  _EventHandlerVars.event = variable("$event");
5853
5872
  })();
5854
5873
  function convertActionBinding(localResolver, implicitReceiver, action, bindingId, baseSourceSpan, implicitReceiverAccesses, globals) {
5855
- if (!localResolver) {
5856
- localResolver = new DefaultLocalResolver(globals);
5857
- }
5858
- const actionWithoutBuiltins = convertPropertyBindingBuiltins({
5859
- createLiteralArrayConverter: (argCount) => {
5860
- return (args) => literalArr(args);
5861
- },
5862
- createLiteralMapConverter: (keys) => {
5863
- return (values) => {
5864
- const entries = keys.map((k, i) => ({
5865
- key: k.key,
5866
- value: values[i],
5867
- quoted: k.quoted
5868
- }));
5869
- return literalMap(entries);
5870
- };
5871
- },
5872
- createPipeConverter: (name) => {
5873
- throw new Error(`Illegal State: Actions are not allowed to contain pipes. Pipe: ${name}`);
5874
- }
5875
- }, action);
5874
+ localResolver != null ? localResolver : localResolver = new DefaultLocalResolver(globals);
5876
5875
  const visitor = new _AstToIrVisitor(localResolver, implicitReceiver, bindingId, false, baseSourceSpan, implicitReceiverAccesses);
5877
5876
  const actionStmts = [];
5878
- flattenStatements(actionWithoutBuiltins.visit(visitor, _Mode.Statement), actionStmts);
5877
+ flattenStatements(convertActionBuiltins(action).visit(visitor, _Mode.Statement), actionStmts);
5879
5878
  prependTemporaryDecls(visitor.temporaryCount, bindingId, actionStmts);
5880
5879
  if (visitor.usesImplicitReceiver) {
5881
5880
  localResolver.notifyImplicitReceiverUse();
@@ -5889,6 +5888,55 @@ function convertActionBinding(localResolver, implicitReceiver, action, bindingId
5889
5888
  }
5890
5889
  return actionStmts;
5891
5890
  }
5891
+ function convertAssignmentActionBinding(localResolver, implicitReceiver, action, bindingId, baseSourceSpan, implicitReceiverAccesses, globals) {
5892
+ localResolver != null ? localResolver : localResolver = new DefaultLocalResolver(globals);
5893
+ const visitor = new _AstToIrVisitor(localResolver, implicitReceiver, bindingId, false, baseSourceSpan, implicitReceiverAccesses);
5894
+ let convertedAction = convertActionBuiltins(action).visit(visitor, _Mode.Statement);
5895
+ if (!(convertedAction instanceof ExpressionStatement)) {
5896
+ throw new Error(`Illegal state: unsupported expression in two-way action binding.`);
5897
+ }
5898
+ convertedAction = wrapAssignmentAction(convertedAction.expr).toStmt();
5899
+ const actionStmts = [];
5900
+ flattenStatements(convertedAction, actionStmts);
5901
+ prependTemporaryDecls(visitor.temporaryCount, bindingId, actionStmts);
5902
+ actionStmts.push(new ReturnStatement(EventHandlerVars.event));
5903
+ implicitReceiverAccesses == null ? void 0 : implicitReceiverAccesses.add(EventHandlerVars.event.name);
5904
+ if (visitor.usesImplicitReceiver) {
5905
+ localResolver.notifyImplicitReceiverUse();
5906
+ }
5907
+ return actionStmts;
5908
+ }
5909
+ function wrapAssignmentReadExpression(ast) {
5910
+ return new ExternalExpr(Identifiers.twoWayBindingSet).callFn([ast, EventHandlerVars.event]).or(ast.set(EventHandlerVars.event));
5911
+ }
5912
+ function isReadExpression(value) {
5913
+ return value instanceof ReadPropExpr || value instanceof ReadKeyExpr;
5914
+ }
5915
+ function wrapAssignmentAction(ast) {
5916
+ if (isReadExpression(ast)) {
5917
+ return wrapAssignmentReadExpression(ast);
5918
+ }
5919
+ if (ast instanceof BinaryOperatorExpr && isReadExpression(ast.rhs)) {
5920
+ return new BinaryOperatorExpr(ast.operator, ast.lhs, wrapAssignmentReadExpression(ast.rhs));
5921
+ }
5922
+ if (ast instanceof ConditionalExpr && isReadExpression(ast.falseCase)) {
5923
+ return new ConditionalExpr(ast.condition, ast.trueCase, wrapAssignmentReadExpression(ast.falseCase));
5924
+ }
5925
+ if (ast instanceof NotExpr) {
5926
+ let expr = ast.condition;
5927
+ while (true) {
5928
+ if (expr instanceof NotExpr) {
5929
+ expr = expr.condition;
5930
+ } else {
5931
+ if (isReadExpression(expr)) {
5932
+ return wrapAssignmentReadExpression(expr);
5933
+ }
5934
+ break;
5935
+ }
5936
+ }
5937
+ }
5938
+ throw new Error(`Illegal state: unsupported expression in two-way action binding.`);
5939
+ }
5892
5940
  function convertPropertyBindingBuiltins(converterFactory, ast) {
5893
5941
  return convertBuiltins(converterFactory, ast);
5894
5942
  }
@@ -5950,6 +5998,27 @@ function convertBuiltins(converterFactory, ast) {
5950
5998
  const visitor = new _BuiltinAstConverter(converterFactory);
5951
5999
  return ast.visit(visitor);
5952
6000
  }
6001
+ function convertActionBuiltins(action) {
6002
+ const converterFactory = {
6003
+ createLiteralArrayConverter: () => {
6004
+ return (args) => literalArr(args);
6005
+ },
6006
+ createLiteralMapConverter: (keys) => {
6007
+ return (values) => {
6008
+ const entries = keys.map((k, i) => ({
6009
+ key: k.key,
6010
+ value: values[i],
6011
+ quoted: k.quoted
6012
+ }));
6013
+ return literalMap(entries);
6014
+ };
6015
+ },
6016
+ createPipeConverter: (name) => {
6017
+ throw new Error(`Illegal State: Actions are not allowed to contain pipes. Pipe: ${name}`);
6018
+ }
6019
+ };
6020
+ return convertPropertyBindingBuiltins(converterFactory, action);
6021
+ }
5953
6022
  function temporaryName(bindingId, temporaryNumber) {
5954
6023
  return `tmp_${bindingId}_${temporaryNumber}`;
5955
6024
  }
@@ -7054,16 +7123,18 @@ var OpKind;
7054
7123
  OpKind2[OpKind2["Projection"] = 33] = "Projection";
7055
7124
  OpKind2[OpKind2["RepeaterCreate"] = 34] = "RepeaterCreate";
7056
7125
  OpKind2[OpKind2["Repeater"] = 35] = "Repeater";
7057
- OpKind2[OpKind2["I18nStart"] = 36] = "I18nStart";
7058
- OpKind2[OpKind2["I18n"] = 37] = "I18n";
7059
- OpKind2[OpKind2["I18nEnd"] = 38] = "I18nEnd";
7060
- OpKind2[OpKind2["I18nExpression"] = 39] = "I18nExpression";
7061
- OpKind2[OpKind2["I18nApply"] = 40] = "I18nApply";
7062
- OpKind2[OpKind2["IcuStart"] = 41] = "IcuStart";
7063
- OpKind2[OpKind2["IcuEnd"] = 42] = "IcuEnd";
7064
- OpKind2[OpKind2["IcuPlaceholder"] = 43] = "IcuPlaceholder";
7065
- OpKind2[OpKind2["I18nContext"] = 44] = "I18nContext";
7066
- OpKind2[OpKind2["I18nAttributes"] = 45] = "I18nAttributes";
7126
+ OpKind2[OpKind2["TwoWayProperty"] = 36] = "TwoWayProperty";
7127
+ OpKind2[OpKind2["TwoWayListener"] = 37] = "TwoWayListener";
7128
+ OpKind2[OpKind2["I18nStart"] = 38] = "I18nStart";
7129
+ OpKind2[OpKind2["I18n"] = 39] = "I18n";
7130
+ OpKind2[OpKind2["I18nEnd"] = 40] = "I18nEnd";
7131
+ OpKind2[OpKind2["I18nExpression"] = 41] = "I18nExpression";
7132
+ OpKind2[OpKind2["I18nApply"] = 42] = "I18nApply";
7133
+ OpKind2[OpKind2["IcuStart"] = 43] = "IcuStart";
7134
+ OpKind2[OpKind2["IcuEnd"] = 44] = "IcuEnd";
7135
+ OpKind2[OpKind2["IcuPlaceholder"] = 45] = "IcuPlaceholder";
7136
+ OpKind2[OpKind2["I18nContext"] = 46] = "I18nContext";
7137
+ OpKind2[OpKind2["I18nAttributes"] = 47] = "I18nAttributes";
7067
7138
  })(OpKind || (OpKind = {}));
7068
7139
  var ExpressionKind;
7069
7140
  (function(ExpressionKind2) {
@@ -7093,6 +7164,7 @@ var ExpressionKind;
7093
7164
  ExpressionKind2[ExpressionKind2["ConditionalCase"] = 23] = "ConditionalCase";
7094
7165
  ExpressionKind2[ExpressionKind2["DerivedRepeaterVar"] = 24] = "DerivedRepeaterVar";
7095
7166
  ExpressionKind2[ExpressionKind2["ConstCollected"] = 25] = "ConstCollected";
7167
+ ExpressionKind2[ExpressionKind2["TwoWayBindingSet"] = 26] = "TwoWayBindingSet";
7096
7168
  })(ExpressionKind || (ExpressionKind = {}));
7097
7169
  var VariableFlags;
7098
7170
  (function(VariableFlags2) {
@@ -7126,6 +7198,7 @@ var BindingKind;
7126
7198
  BindingKind2[BindingKind2["Template"] = 4] = "Template";
7127
7199
  BindingKind2[BindingKind2["I18n"] = 5] = "I18n";
7128
7200
  BindingKind2[BindingKind2["Animation"] = 6] = "Animation";
7201
+ BindingKind2[BindingKind2["TwoWayProperty"] = 7] = "TwoWayProperty";
7129
7202
  })(BindingKind || (BindingKind = {}));
7130
7203
  var I18nParamResolutionTime;
7131
7204
  (function(I18nParamResolutionTime2) {
@@ -7280,6 +7353,21 @@ function createPropertyOp(target, name, expression, isAnimationTrigger, security
7280
7353
  sourceSpan
7281
7354
  }, TRAIT_DEPENDS_ON_SLOT_CONTEXT), TRAIT_CONSUMES_VARS), NEW_OP);
7282
7355
  }
7356
+ function createTwoWayPropertyOp(target, name, expression, securityContext, isStructuralTemplateAttribute, templateKind, i18nContext, i18nMessage, sourceSpan) {
7357
+ return __spreadValues(__spreadValues(__spreadValues({
7358
+ kind: OpKind.TwoWayProperty,
7359
+ target,
7360
+ name,
7361
+ expression,
7362
+ securityContext,
7363
+ sanitizer: null,
7364
+ isStructuralTemplateAttribute,
7365
+ templateKind,
7366
+ i18nContext,
7367
+ i18nMessage,
7368
+ sourceSpan
7369
+ }, TRAIT_DEPENDS_ON_SLOT_CONTEXT), TRAIT_CONSUMES_VARS), NEW_OP);
7370
+ }
7283
7371
  function createStylePropOp(xref, name, expression, unit, sourceSpan) {
7284
7372
  return __spreadValues(__spreadValues(__spreadValues({
7285
7373
  kind: OpKind.StyleProp,
@@ -7587,6 +7675,31 @@ var ResetViewExpr = class extends ExpressionBase {
7587
7675
  return new ResetViewExpr(this.expr.clone());
7588
7676
  }
7589
7677
  };
7678
+ var TwoWayBindingSetExpr = class extends ExpressionBase {
7679
+ constructor(target, value) {
7680
+ super();
7681
+ this.target = target;
7682
+ this.value = value;
7683
+ this.kind = ExpressionKind.TwoWayBindingSet;
7684
+ }
7685
+ visitExpression(visitor, context) {
7686
+ this.target.visitExpression(visitor, context);
7687
+ this.value.visitExpression(visitor, context);
7688
+ }
7689
+ isEquivalent(other) {
7690
+ return this.target.isEquivalent(other.target) && this.value.isEquivalent(other.value);
7691
+ }
7692
+ isConstant() {
7693
+ return false;
7694
+ }
7695
+ transformInternalExpressions(transform2, flags) {
7696
+ this.target = transformExpressionsInExpression(this.target, transform2, flags);
7697
+ this.value = transformExpressionsInExpression(this.value, transform2, flags);
7698
+ }
7699
+ clone() {
7700
+ return new TwoWayBindingSetExpr(this.target, this.value);
7701
+ }
7702
+ };
7590
7703
  var ReadVariableExpr = class extends ExpressionBase {
7591
7704
  constructor(xref) {
7592
7705
  super();
@@ -8038,6 +8151,10 @@ function transformExpressionsInOp(op, transform2, flags) {
8038
8151
  }
8039
8152
  op.sanitizer = op.sanitizer && transformExpressionsInExpression(op.sanitizer, transform2, flags);
8040
8153
  break;
8154
+ case OpKind.TwoWayProperty:
8155
+ op.expression = transformExpressionsInExpression(op.expression, transform2, flags);
8156
+ op.sanitizer = op.sanitizer && transformExpressionsInExpression(op.sanitizer, transform2, flags);
8157
+ break;
8041
8158
  case OpKind.I18nExpression:
8042
8159
  op.expression = transformExpressionsInExpression(op.expression, transform2, flags);
8043
8160
  break;
@@ -8065,6 +8182,7 @@ function transformExpressionsInOp(op, transform2, flags) {
8065
8182
  }
8066
8183
  break;
8067
8184
  case OpKind.Listener:
8185
+ case OpKind.TwoWayListener:
8068
8186
  for (const innerOp of op.handlerOps) {
8069
8187
  transformExpressionsInOp(innerOp, transform2, flags | VisitorContextFlag.InChildOperation);
8070
8188
  }
@@ -8546,6 +8664,20 @@ function createListenerOp(target, targetSlot, name, tag, handlerOps, animationPh
8546
8664
  sourceSpan
8547
8665
  }, NEW_OP);
8548
8666
  }
8667
+ function createTwoWayListenerOp(target, targetSlot, name, tag, handlerOps, sourceSpan) {
8668
+ const handlerList = new OpList();
8669
+ handlerList.push(handlerOps);
8670
+ return __spreadValues({
8671
+ kind: OpKind.TwoWayListener,
8672
+ target,
8673
+ targetSlot,
8674
+ tag,
8675
+ name,
8676
+ handlerOps: handlerList,
8677
+ handlerFnName: null,
8678
+ sourceSpan
8679
+ }, NEW_OP);
8680
+ }
8549
8681
  function createPipeOp(xref, slot, name) {
8550
8682
  return __spreadValues(__spreadValues({
8551
8683
  kind: OpKind.Pipe,
@@ -8796,7 +8928,7 @@ var CompilationUnit = class {
8796
8928
  *ops() {
8797
8929
  for (const op of this.create) {
8798
8930
  yield op;
8799
- if (op.kind === OpKind.Listener) {
8931
+ if (op.kind === OpKind.Listener || op.kind === OpKind.TwoWayListener) {
8800
8932
  for (const listenerOp of op.handlerOps) {
8801
8933
  yield listenerOp;
8802
8934
  }
@@ -8991,6 +9123,18 @@ function extractAttributes(job) {
8991
9123
  );
8992
9124
  }
8993
9125
  break;
9126
+ case OpKind.TwoWayProperty:
9127
+ OpList.insertBefore(createExtractedAttributeOp(
9128
+ op.target,
9129
+ BindingKind.TwoWayProperty,
9130
+ null,
9131
+ op.name,
9132
+ null,
9133
+ null,
9134
+ null,
9135
+ op.securityContext
9136
+ ), lookupElement(elements, op.target));
9137
+ break;
8994
9138
  case OpKind.StyleProp:
8995
9139
  case OpKind.ClassProp:
8996
9140
  if (unit.job.compatibility === CompatibilityMode.TemplateDefinitionBuilder && op.expression instanceof EmptyExpr2) {
@@ -9028,6 +9172,21 @@ function extractAttributes(job) {
9028
9172
  }
9029
9173
  }
9030
9174
  break;
9175
+ case OpKind.TwoWayListener:
9176
+ if (job.kind !== CompilationJobKind.Host) {
9177
+ const extractedAttributeOp = createExtractedAttributeOp(
9178
+ op.target,
9179
+ BindingKind.Property,
9180
+ null,
9181
+ op.name,
9182
+ null,
9183
+ null,
9184
+ null,
9185
+ SecurityContext.NONE
9186
+ );
9187
+ OpList.insertBefore(extractedAttributeOp, lookupElement(elements, op.target));
9188
+ }
9189
+ break;
9031
9190
  }
9032
9191
  }
9033
9192
  }
@@ -9101,6 +9260,12 @@ function specializeBindings(job) {
9101
9260
  OpList.replace(op, createPropertyOp(op.target, op.name, op.expression, op.bindingKind === BindingKind.Animation, op.securityContext, op.isStructuralTemplateAttribute, op.templateKind, op.i18nContext, op.i18nMessage, op.sourceSpan));
9102
9261
  }
9103
9262
  break;
9263
+ case BindingKind.TwoWayProperty:
9264
+ if (!(op.expression instanceof Expression)) {
9265
+ throw new Error(`Expected value of two-way property binding "${op.name}" to be an expression`);
9266
+ }
9267
+ OpList.replace(op, createTwoWayPropertyOp(op.target, op.name, op.expression, op.securityContext, op.isStructuralTemplateAttribute, op.templateKind, op.i18nContext, op.i18nMessage, op.sourceSpan));
9268
+ break;
9104
9269
  case BindingKind.I18n:
9105
9270
  case BindingKind.ClassName:
9106
9271
  case BindingKind.StyleProperty:
@@ -9137,7 +9302,9 @@ var CHAINABLE = /* @__PURE__ */ new Set([
9137
9302
  Identifiers.stylePropInterpolateV,
9138
9303
  Identifiers.syntheticHostListener,
9139
9304
  Identifiers.syntheticHostProperty,
9140
- Identifiers.templateCreate
9305
+ Identifiers.templateCreate,
9306
+ Identifiers.twoWayProperty,
9307
+ Identifiers.twoWayListener
9141
9308
  ]);
9142
9309
  function chain(job) {
9143
9310
  for (const unit of job.units) {
@@ -9346,7 +9513,7 @@ var ElementAttributes = class {
9346
9513
  }
9347
9514
  get bindings() {
9348
9515
  var _a2;
9349
- return (_a2 = this.byKind.get(BindingKind.Property)) != null ? _a2 : FLYWEIGHT_ARRAY;
9516
+ return (_a2 = this.propertyBindings) != null ? _a2 : FLYWEIGHT_ARRAY;
9350
9517
  }
9351
9518
  get template() {
9352
9519
  var _a2;
@@ -9360,6 +9527,7 @@ var ElementAttributes = class {
9360
9527
  this.compatibility = compatibility;
9361
9528
  this.known = /* @__PURE__ */ new Map();
9362
9529
  this.byKind = /* @__PURE__ */ new Map();
9530
+ this.propertyBindings = null;
9363
9531
  this.projectAs = null;
9364
9532
  }
9365
9533
  isKnown(kind, name, value) {
@@ -9401,10 +9569,16 @@ var ElementAttributes = class {
9401
9569
  }
9402
9570
  }
9403
9571
  arrayFor(kind) {
9404
- if (!this.byKind.has(kind)) {
9405
- this.byKind.set(kind, []);
9572
+ var _a2;
9573
+ if (kind === BindingKind.Property || kind === BindingKind.TwoWayProperty) {
9574
+ (_a2 = this.propertyBindings) != null ? _a2 : this.propertyBindings = [];
9575
+ return this.propertyBindings;
9576
+ } else {
9577
+ if (!this.byKind.has(kind)) {
9578
+ this.byKind.set(kind, []);
9579
+ }
9580
+ return this.byKind.get(kind);
9406
9581
  }
9407
- return this.byKind.get(kind);
9408
9582
  }
9409
9583
  };
9410
9584
  function getAttributeNameLiterals(namespace, name) {
@@ -9494,7 +9668,10 @@ function createDeferDepsFns(job) {
9494
9668
  const dependencies = [];
9495
9669
  for (const dep of op.metadata.deps) {
9496
9670
  if (dep.isDeferrable) {
9497
- const innerFn = arrowFn([new FnParam("m", DYNAMIC_TYPE)], variable("m").prop(dep.symbolName));
9671
+ const innerFn = arrowFn(
9672
+ [new FnParam("m", DYNAMIC_TYPE)],
9673
+ variable("m").prop(dep.isDefaultImport ? "default" : dep.symbolName)
9674
+ );
9498
9675
  const importExpr2 = new DynamicImportExpr(dep.importPath).prop("then").callFn([innerFn]);
9499
9676
  dependencies.push(importExpr2);
9500
9677
  } else {
@@ -10100,6 +10277,7 @@ function recursivelyProcessView(view, parentScope) {
10100
10277
  }
10101
10278
  break;
10102
10279
  case OpKind.Listener:
10280
+ case OpKind.TwoWayListener:
10103
10281
  op.handlerOps.prepend(generateVariablesInScopeForView(view, scope));
10104
10282
  break;
10105
10283
  }
@@ -10671,15 +10849,11 @@ var Parser = class {
10671
10849
  this._lexer = _lexer;
10672
10850
  this.errors = [];
10673
10851
  }
10674
- parseAction(input, isAssignmentEvent, location, absoluteOffset, interpolationConfig = DEFAULT_INTERPOLATION_CONFIG) {
10852
+ parseAction(input, location, absoluteOffset, interpolationConfig = DEFAULT_INTERPOLATION_CONFIG) {
10675
10853
  this._checkNoInterpolation(input, location, interpolationConfig);
10676
10854
  const sourceToLex = this._stripComments(input);
10677
10855
  const tokens = this._lexer.tokenize(sourceToLex);
10678
- let flags = 1;
10679
- if (isAssignmentEvent) {
10680
- flags |= 2;
10681
- }
10682
- const ast = new _ParseAST(input, location, absoluteOffset, tokens, flags, this.errors, 0).parseChain();
10856
+ const ast = new _ParseAST(input, location, absoluteOffset, tokens, 1, this.errors, 0).parseChain();
10683
10857
  return new ASTWithSource(ast, input, location, absoluteOffset, this.errors);
10684
10858
  }
10685
10859
  parseBinding(input, location, absoluteOffset, interpolationConfig = DEFAULT_INTERPOLATION_CONFIG) {
@@ -11032,7 +11206,7 @@ var _ParseAST = class {
11032
11206
  let result = this.parseExpression();
11033
11207
  if (this.consumeOptionalOperator("|")) {
11034
11208
  if (this.parseFlags & 1) {
11035
- this.error("Cannot have a pipe in an action expression");
11209
+ this.error(`Cannot have a pipe in an action expression`);
11036
11210
  }
11037
11211
  do {
11038
11212
  const nameStart = this.inputIndex;
@@ -11326,14 +11500,14 @@ var _ParseAST = class {
11326
11500
  const nameSpan = this.sourceSpan(nameStart);
11327
11501
  let receiver;
11328
11502
  if (isSafe) {
11329
- if (this.consumeOptionalAssignment()) {
11503
+ if (this.consumeOptionalOperator("=")) {
11330
11504
  this.error("The '?.' operator cannot be used in the assignment");
11331
11505
  receiver = new EmptyExpr(this.span(start), this.sourceSpan(start));
11332
11506
  } else {
11333
11507
  receiver = new SafePropertyRead(this.span(start), this.sourceSpan(start), nameSpan, readReceiver, id);
11334
11508
  }
11335
11509
  } else {
11336
- if (this.consumeOptionalAssignment()) {
11510
+ if (this.consumeOptionalOperator("=")) {
11337
11511
  if (!(this.parseFlags & 1)) {
11338
11512
  this.error("Bindings cannot contain assignments");
11339
11513
  return new EmptyExpr(this.span(start), this.sourceSpan(start));
@@ -11357,14 +11531,6 @@ var _ParseAST = class {
11357
11531
  const sourceSpan = this.sourceSpan(start);
11358
11532
  return isSafe ? new SafeCall(span, sourceSpan, receiver, args, argumentSpan) : new Call(span, sourceSpan, receiver, args, argumentSpan);
11359
11533
  }
11360
- consumeOptionalAssignment() {
11361
- if (this.parseFlags & 2 && this.next.isOperator("!") && this.peek(1).isOperator("=")) {
11362
- this.advance();
11363
- this.advance();
11364
- return true;
11365
- }
11366
- return this.consumeOptionalOperator("=");
11367
- }
11368
11534
  parseCallArguments() {
11369
11535
  if (this.next.isCharacter($RPAREN))
11370
11536
  return [];
@@ -16572,7 +16738,7 @@ function nameFunctionsAndVariables(job) {
16572
16738
  }
16573
16739
  function addNamesToView(unit, baseName, state, compatibility) {
16574
16740
  if (unit.fnName === null) {
16575
- unit.fnName = sanitizeIdentifier(`${baseName}_${unit.job.fnSuffix}`);
16741
+ unit.fnName = unit.job.pool.uniqueName(sanitizeIdentifier(`${baseName}_${unit.job.fnSuffix}`), false);
16576
16742
  }
16577
16743
  const varNames = /* @__PURE__ */ new Map();
16578
16744
  for (const op of unit.ops()) {
@@ -16602,6 +16768,15 @@ function addNamesToView(unit, baseName, state, compatibility) {
16602
16768
  }
16603
16769
  op.handlerFnName = sanitizeIdentifier(op.handlerFnName);
16604
16770
  break;
16771
+ case OpKind.TwoWayListener:
16772
+ if (op.handlerFnName !== null) {
16773
+ break;
16774
+ }
16775
+ if (op.targetSlot.slot === null) {
16776
+ throw new Error(`Expected a slot to be assigned`);
16777
+ }
16778
+ op.handlerFnName = sanitizeIdentifier(`${unit.fnName}_${op.tag.replace("-", "_")}_${op.name}_${op.targetSlot.slot}_listener`);
16779
+ break;
16605
16780
  case OpKind.Variable:
16606
16781
  varNames.set(op.xref, getVariableName(unit, op.variable, state));
16607
16782
  break;
@@ -16690,7 +16865,7 @@ function stripImportant(name) {
16690
16865
  function mergeNextContextExpressions(job) {
16691
16866
  for (const unit of job.units) {
16692
16867
  for (const op of unit.create) {
16693
- if (op.kind === OpKind.Listener) {
16868
+ if (op.kind === OpKind.Listener || op.kind === OpKind.TwoWayListener) {
16694
16869
  mergeNextContextsInOps(op.handlerOps);
16695
16870
  }
16696
16871
  }
@@ -16804,9 +16979,15 @@ function kindWithInterpolationTest(kind, interpolation) {
16804
16979
  return op.kind === kind && interpolation === op.expression instanceof Interpolation2;
16805
16980
  };
16806
16981
  }
16982
+ function basicListenerKindTest(op) {
16983
+ return op.kind === OpKind.Listener && !(op.hostListener && op.isAnimationListener) || op.kind === OpKind.TwoWayListener;
16984
+ }
16985
+ function nonInterpolationPropertyKindTest(op) {
16986
+ return (op.kind === OpKind.Property || op.kind === OpKind.TwoWayProperty) && !(op.expression instanceof Interpolation2);
16987
+ }
16807
16988
  var CREATE_ORDERING = [
16808
16989
  { test: (op) => op.kind === OpKind.Listener && op.hostListener && op.isAnimationListener },
16809
- { test: (op) => op.kind === OpKind.Listener && !(op.hostListener && op.isAnimationListener) }
16990
+ { test: basicListenerKindTest }
16810
16991
  ];
16811
16992
  var UPDATE_ORDERING = [
16812
16993
  { test: kindTest(OpKind.StyleMap), transform: keepLast },
@@ -16815,7 +16996,7 @@ var UPDATE_ORDERING = [
16815
16996
  { test: kindTest(OpKind.ClassProp) },
16816
16997
  { test: kindWithInterpolationTest(OpKind.Attribute, true) },
16817
16998
  { test: kindWithInterpolationTest(OpKind.Property, true) },
16818
- { test: kindWithInterpolationTest(OpKind.Property, false) },
16999
+ { test: nonInterpolationPropertyKindTest },
16819
17000
  { test: kindWithInterpolationTest(OpKind.Attribute, false) }
16820
17001
  ];
16821
17002
  var UPDATE_HOST_ORDERING = [
@@ -16829,11 +17010,13 @@ var UPDATE_HOST_ORDERING = [
16829
17010
  ];
16830
17011
  var handledOpKinds = /* @__PURE__ */ new Set([
16831
17012
  OpKind.Listener,
17013
+ OpKind.TwoWayListener,
16832
17014
  OpKind.StyleMap,
16833
17015
  OpKind.ClassMap,
16834
17016
  OpKind.StyleProp,
16835
17017
  OpKind.ClassProp,
16836
17018
  OpKind.Property,
17019
+ OpKind.TwoWayProperty,
16837
17020
  OpKind.HostProperty,
16838
17021
  OpKind.Attribute
16839
17022
  ]);
@@ -17213,6 +17396,12 @@ function listener(name, handlerFn, eventTargetResolver, syntheticHost, sourceSpa
17213
17396
  }
17214
17397
  return call(syntheticHost ? Identifiers.syntheticHostListener : Identifiers.listener, args, sourceSpan);
17215
17398
  }
17399
+ function twoWayBindingSet(target, value) {
17400
+ return importExpr(Identifiers.twoWayBindingSet).callFn([target, value]);
17401
+ }
17402
+ function twoWayListener(name, handlerFn, sourceSpan) {
17403
+ return call(Identifiers.twoWayListener, [literal(name), handlerFn], sourceSpan);
17404
+ }
17216
17405
  function pipe(slot, name) {
17217
17406
  return call(Identifiers.pipe, [
17218
17407
  literal(slot),
@@ -17373,6 +17562,13 @@ function property(name, expression, sanitizer, sourceSpan) {
17373
17562
  }
17374
17563
  return call(Identifiers.property, args, sourceSpan);
17375
17564
  }
17565
+ function twoWayProperty(name, expression, sanitizer, sourceSpan) {
17566
+ const args = [literal(name), expression];
17567
+ if (sanitizer !== null) {
17568
+ args.push(sanitizer);
17569
+ }
17570
+ return call(Identifiers.twoWayProperty, args, sourceSpan);
17571
+ }
17376
17572
  function attribute(name, expression, sanitizer, namespace) {
17377
17573
  const args = [literal(name), expression];
17378
17574
  if (sanitizer !== null || namespace !== null) {
@@ -17749,6 +17945,9 @@ function reifyCreateOperations(unit, ops) {
17749
17945
  }
17750
17946
  OpList.replace(op, listener(op.name, listenerFn, eventTargetResolver, op.hostListener && op.isAnimationListener, op.sourceSpan));
17751
17947
  break;
17948
+ case OpKind.TwoWayListener:
17949
+ OpList.replace(op, twoWayListener(op.name, reifyListenerHandler(unit, op.handlerFnName, op.handlerOps, true), op.sourceSpan));
17950
+ break;
17752
17951
  case OpKind.Variable:
17753
17952
  if (op.variable.name === null) {
17754
17953
  throw new Error(`AssertionError: unnamed variable ${op.xref}`);
@@ -17855,6 +18054,9 @@ function reifyUpdateOperations(_unit, ops) {
17855
18054
  OpList.replace(op, property(op.name, op.expression, op.sanitizer, op.sourceSpan));
17856
18055
  }
17857
18056
  break;
18057
+ case OpKind.TwoWayProperty:
18058
+ OpList.replace(op, twoWayProperty(op.name, op.expression, op.sanitizer, op.sourceSpan));
18059
+ break;
17858
18060
  case OpKind.StyleProp:
17859
18061
  if (op.expression instanceof Interpolation2) {
17860
18062
  OpList.replace(op, stylePropInterpolate(op.name, op.expression.strings, op.expression.expressions, op.unit, op.sourceSpan));
@@ -17945,6 +18147,8 @@ function reifyIrExpression(expr) {
17945
18147
  return reference(expr.targetSlot.slot + 1 + expr.offset);
17946
18148
  case ExpressionKind.LexicalRead:
17947
18149
  throw new Error(`AssertionError: unresolved LexicalRead of ${expr.name}`);
18150
+ case ExpressionKind.TwoWayBindingSet:
18151
+ throw new Error(`AssertionError: unresolved TwoWayBindingSet`);
17948
18152
  case ExpressionKind.RestoreView:
17949
18153
  if (typeof expr.view === "number") {
17950
18154
  throw new Error(`AssertionError: unresolved RestoreView`);
@@ -18081,6 +18285,7 @@ function processLexicalScope(view, ops) {
18081
18285
  }
18082
18286
  break;
18083
18287
  case OpKind.Listener:
18288
+ case OpKind.TwoWayListener:
18084
18289
  processLexicalScope(view, op.handlerOps);
18085
18290
  break;
18086
18291
  }
@@ -18111,10 +18316,12 @@ function resolveDollarEvent(job) {
18111
18316
  }
18112
18317
  function transformDollarEvent(unit, ops) {
18113
18318
  for (const op of ops) {
18114
- if (op.kind === OpKind.Listener) {
18319
+ if (op.kind === OpKind.Listener || op.kind === OpKind.TwoWayListener) {
18115
18320
  transformExpressionsInOp(op, (expr) => {
18116
18321
  if (expr instanceof LexicalReadExpr && expr.name === "$event") {
18117
- op.consumesDollarEvent = true;
18322
+ if (op.kind === OpKind.Listener) {
18323
+ op.consumesDollarEvent = true;
18324
+ }
18118
18325
  return new ReadVarExpr(expr.name);
18119
18326
  }
18120
18327
  return expr;
@@ -18384,12 +18591,13 @@ function processLexicalScope2(unit, ops, savedView) {
18384
18591
  }
18385
18592
  break;
18386
18593
  case OpKind.Listener:
18594
+ case OpKind.TwoWayListener:
18387
18595
  processLexicalScope2(unit, op.handlerOps, savedView);
18388
18596
  break;
18389
18597
  }
18390
18598
  }
18391
18599
  for (const op of ops) {
18392
- if (op.kind == OpKind.Listener) {
18600
+ if (op.kind == OpKind.Listener || op.kind === OpKind.TwoWayListener) {
18393
18601
  continue;
18394
18602
  }
18395
18603
  transformExpressionsInOp(op, (expr, flags) => {
@@ -18489,6 +18697,53 @@ function getOnlySecurityContext(securityContext) {
18489
18697
  return securityContext;
18490
18698
  }
18491
18699
 
18700
+ // bazel-out/k8-fastbuild/bin/packages/compiler/src/template/pipeline/src/phases/transform_two_way_binding_set.mjs
18701
+ function transformTwoWayBindingSet(job) {
18702
+ for (const unit of job.units) {
18703
+ for (const op of unit.create) {
18704
+ if (op.kind === OpKind.TwoWayListener) {
18705
+ transformExpressionsInOp(op, (expr) => {
18706
+ if (expr instanceof TwoWayBindingSetExpr) {
18707
+ return wrapAction(expr.target, expr.value);
18708
+ }
18709
+ return expr;
18710
+ }, VisitorContextFlag.InChildOperation);
18711
+ }
18712
+ }
18713
+ }
18714
+ }
18715
+ function wrapSetOperation(target, value) {
18716
+ return twoWayBindingSet(target, value).or(target.set(value));
18717
+ }
18718
+ function isReadExpression2(value) {
18719
+ return value instanceof ReadPropExpr || value instanceof ReadKeyExpr;
18720
+ }
18721
+ function wrapAction(target, value) {
18722
+ if (isReadExpression2(target)) {
18723
+ return wrapSetOperation(target, value);
18724
+ }
18725
+ if (target instanceof BinaryOperatorExpr && isReadExpression2(target.rhs)) {
18726
+ return new BinaryOperatorExpr(target.operator, target.lhs, wrapSetOperation(target.rhs, value));
18727
+ }
18728
+ if (target instanceof ConditionalExpr && isReadExpression2(target.falseCase)) {
18729
+ return new ConditionalExpr(target.condition, target.trueCase, wrapSetOperation(target.falseCase, value));
18730
+ }
18731
+ if (target instanceof NotExpr) {
18732
+ let expr = target.condition;
18733
+ while (true) {
18734
+ if (expr instanceof NotExpr) {
18735
+ expr = expr.condition;
18736
+ } else {
18737
+ if (isReadExpression2(expr)) {
18738
+ return wrapSetOperation(expr, value);
18739
+ }
18740
+ break;
18741
+ }
18742
+ }
18743
+ }
18744
+ throw new Error(`Unsupported expression in two-way action binding.`);
18745
+ }
18746
+
18492
18747
  // bazel-out/k8-fastbuild/bin/packages/compiler/src/template/pipeline/src/phases/save_restore_view.mjs
18493
18748
  function saveAndRestoreView(job) {
18494
18749
  for (const unit of job.units) {
@@ -18500,7 +18755,7 @@ function saveAndRestoreView(job) {
18500
18755
  }, new GetCurrentViewExpr(), VariableFlags.None)
18501
18756
  ]);
18502
18757
  for (const op of unit.create) {
18503
- if (op.kind !== OpKind.Listener) {
18758
+ if (op.kind !== OpKind.Listener && op.kind !== OpKind.TwoWayListener) {
18504
18759
  continue;
18505
18760
  }
18506
18761
  let needsRestoreView = unit !== job.root;
@@ -18633,7 +18888,7 @@ function generateTemporaries(ops) {
18633
18888
  });
18634
18889
  generatedStatements.push(...Array.from(new Set(defs.values())).map((name) => createStatementOp(new DeclareVarStmt(name))));
18635
18890
  opCount++;
18636
- if (op.kind === OpKind.Listener) {
18891
+ if (op.kind === OpKind.Listener || op.kind === OpKind.TwoWayListener) {
18637
18892
  op.handlerOps.prepend(generateTemporaries(op.handlerOps));
18638
18893
  }
18639
18894
  }
@@ -18813,6 +19068,8 @@ function varsUsedByOp(op) {
18813
19068
  slots += op.expression.expressions.length;
18814
19069
  }
18815
19070
  return slots;
19071
+ case OpKind.TwoWayProperty:
19072
+ return 1;
18816
19073
  case OpKind.StyleProp:
18817
19074
  case OpKind.ClassProp:
18818
19075
  case OpKind.StyleMap:
@@ -18862,14 +19119,14 @@ function optimizeVariables(job) {
18862
19119
  inlineAlwaysInlineVariables(unit.create);
18863
19120
  inlineAlwaysInlineVariables(unit.update);
18864
19121
  for (const op of unit.create) {
18865
- if (op.kind === OpKind.Listener) {
19122
+ if (op.kind === OpKind.Listener || op.kind === OpKind.TwoWayListener) {
18866
19123
  inlineAlwaysInlineVariables(op.handlerOps);
18867
19124
  }
18868
19125
  }
18869
19126
  optimizeVariablesInOpList(unit.create, job.compatibility);
18870
19127
  optimizeVariablesInOpList(unit.update, job.compatibility);
18871
19128
  for (const op of unit.create) {
18872
- if (op.kind === OpKind.Listener) {
19129
+ if (op.kind === OpKind.Listener || op.kind === OpKind.TwoWayListener) {
18873
19130
  optimizeVariablesInOpList(op.handlerOps, job.compatibility);
18874
19131
  }
18875
19132
  }
@@ -19170,6 +19427,7 @@ var phases = [
19170
19427
  { kind: CompilationJobKind.Tmpl, fn: generateTrackVariables },
19171
19428
  { kind: CompilationJobKind.Both, fn: resolveNames },
19172
19429
  { kind: CompilationJobKind.Tmpl, fn: resolveDeferTargetNames },
19430
+ { kind: CompilationJobKind.Tmpl, fn: transformTwoWayBindingSet },
19173
19431
  { kind: CompilationJobKind.Tmpl, fn: optimizeTrackFns },
19174
19432
  { kind: CompilationJobKind.Both, fn: resolveContexts },
19175
19433
  { kind: CompilationJobKind.Both, fn: resolveSanitizers },
@@ -19828,7 +20086,7 @@ function convertAstWithInterpolation(job, value, i18nMeta, sourceSpan) {
19828
20086
  }
19829
20087
  var BINDING_KINDS = /* @__PURE__ */ new Map([
19830
20088
  [0, BindingKind.Property],
19831
- [5, BindingKind.Property],
20089
+ [5, BindingKind.TwoWayProperty],
19832
20090
  [1, BindingKind.Attribute],
19833
20091
  [2, BindingKind.ClassName],
19834
20092
  [3, BindingKind.StyleProperty],
@@ -19850,11 +20108,18 @@ function asMessage(i18nMeta) {
19850
20108
  function ingestElementBindings(unit, op, element2) {
19851
20109
  var _a2;
19852
20110
  let bindings = new Array();
20111
+ let i18nAttributeBindingNames = /* @__PURE__ */ new Set();
19853
20112
  for (const attr of element2.attributes) {
19854
20113
  const securityContext = domSchema.securityContext(element2.name, attr.name, true);
19855
20114
  bindings.push(createBindingOp(op.xref, BindingKind.Attribute, attr.name, convertAstWithInterpolation(unit.job, attr.value, attr.i18n), null, securityContext, true, false, null, asMessage(attr.i18n), attr.sourceSpan));
20115
+ if (attr.i18n) {
20116
+ i18nAttributeBindingNames.add(attr.name);
20117
+ }
19856
20118
  }
19857
20119
  for (const input of element2.inputs) {
20120
+ if (i18nAttributeBindingNames.has(input.name)) {
20121
+ console.error(`On component ${unit.job.componentName}, the binding ${input.name} is both an i18n attribute and a property. You may want to remove the property binding. This will become a compilation error in future versions of Angular.`);
20122
+ }
19858
20123
  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, (_a2 = asMessage(input.i18n)) != null ? _a2 : null, input.sourceSpan));
19859
20124
  }
19860
20125
  unit.create.push(bindings.filter((b) => (b == null ? void 0 : b.kind) === OpKind.ExtractedAttribute));
@@ -19863,7 +20128,11 @@ function ingestElementBindings(unit, op, element2) {
19863
20128
  if (output.type === 1 && output.phase === null) {
19864
20129
  throw Error("Animation listener should have a phase");
19865
20130
  }
19866
- unit.create.push(createListenerOp(op.xref, op.handle, output.name, op.tag, makeListenerHandlerOps(unit, output.handler, output.handlerSpan), output.phase, output.target, false, output.sourceSpan));
20131
+ if (output.type === 2) {
20132
+ unit.create.push(createTwoWayListenerOp(op.xref, op.handle, output.name, op.tag, makeTwoWayListenerHandlerOps(unit, output.handler, output.handlerSpan), output.sourceSpan));
20133
+ } else {
20134
+ unit.create.push(createListenerOp(op.xref, op.handle, output.name, op.tag, makeListenerHandlerOps(unit, output.handler, output.handlerSpan), output.phase, output.target, false, output.sourceSpan));
20135
+ }
19867
20136
  }
19868
20137
  if (bindings.some((b) => b == null ? void 0 : b.i18nMessage) !== null) {
19869
20138
  unit.create.push(createI18nAttributesOp(unit.job.allocateXrefId(), new SlotHandle(), op.xref));
@@ -19893,7 +20162,11 @@ function ingestTemplateBindings(unit, op, template2, templateKind) {
19893
20162
  throw Error("Animation listener should have a phase");
19894
20163
  }
19895
20164
  if (templateKind === TemplateKind.NgTemplate) {
19896
- unit.create.push(createListenerOp(op.xref, op.handle, output.name, op.tag, makeListenerHandlerOps(unit, output.handler, output.handlerSpan), output.phase, output.target, false, output.sourceSpan));
20165
+ if (output.type === 2) {
20166
+ unit.create.push(createTwoWayListenerOp(op.xref, op.handle, output.name, op.tag, makeTwoWayListenerHandlerOps(unit, output.handler, output.handlerSpan), output.sourceSpan));
20167
+ } else {
20168
+ unit.create.push(createListenerOp(op.xref, op.handle, output.name, op.tag, makeListenerHandlerOps(unit, output.handler, output.handlerSpan), output.phase, output.target, false, output.sourceSpan));
20169
+ }
19897
20170
  }
19898
20171
  if (templateKind === TemplateKind.Structural && output.type !== 1) {
19899
20172
  const securityContext = domSchema.securityContext(NG_TEMPLATE_TAG_NAME, output.name, false);
@@ -19907,8 +20180,15 @@ function ingestTemplateBindings(unit, op, template2, templateKind) {
19907
20180
  function createTemplateBinding(view, xref, type, name, value, unit, securityContext, isStructuralTemplateAttribute, templateKind, i18nMessage, sourceSpan) {
19908
20181
  const isTextBinding = typeof value === "string";
19909
20182
  if (templateKind === TemplateKind.Structural) {
19910
- if (!isStructuralTemplateAttribute && (type === 0 || type === 5 || type === 2 || type === 3)) {
19911
- return createExtractedAttributeOp(xref, BindingKind.Property, null, name, null, null, i18nMessage, securityContext);
20183
+ if (!isStructuralTemplateAttribute) {
20184
+ switch (type) {
20185
+ case 0:
20186
+ case 2:
20187
+ case 3:
20188
+ return createExtractedAttributeOp(xref, BindingKind.Property, null, name, null, null, i18nMessage, securityContext);
20189
+ case 5:
20190
+ return createExtractedAttributeOp(xref, BindingKind.TwoWayProperty, null, name, null, null, i18nMessage, securityContext);
20191
+ }
19912
20192
  }
19913
20193
  if (!isTextBinding && (type === 1 || type === 4)) {
19914
20194
  return null;
@@ -19935,6 +20215,23 @@ function makeListenerHandlerOps(unit, handler, handlerSpan) {
19935
20215
  handlerOps.push(createStatementOp(new ReturnStatement(returnExpr, returnExpr.sourceSpan)));
19936
20216
  return handlerOps;
19937
20217
  }
20218
+ function makeTwoWayListenerHandlerOps(unit, handler, handlerSpan) {
20219
+ handler = astOf(handler);
20220
+ const handlerOps = new Array();
20221
+ if (handler instanceof Chain) {
20222
+ if (handler.expressions.length === 1) {
20223
+ handler = handler.expressions[0];
20224
+ } else {
20225
+ throw new Error("Expected two-way listener to have a single expression.");
20226
+ }
20227
+ }
20228
+ const handlerExpr = convertAst(handler, unit.job, handlerSpan);
20229
+ const eventReference = new LexicalReadExpr("$event");
20230
+ const twoWaySetExpr = new TwoWayBindingSetExpr(handlerExpr, eventReference);
20231
+ handlerOps.push(createStatementOp(new ExpressionStatement(twoWaySetExpr)));
20232
+ handlerOps.push(createStatementOp(new ReturnStatement(eventReference)));
20233
+ return handlerOps;
20234
+ }
19938
20235
  function astOf(ast) {
19939
20236
  return ast instanceof ASTWithSource ? ast.ast : ast;
19940
20237
  }
@@ -20301,7 +20598,7 @@ var BindingParser = class {
20301
20598
  if (keySpan !== void 0) {
20302
20599
  keySpan = moveParseSourceSpan(keySpan, new AbsoluteSourceSpan(keySpan.start.offset + 1, keySpan.end.offset));
20303
20600
  }
20304
- this._parseAnimationEvent(name, expression, isAssignmentEvent, sourceSpan, handlerSpan, targetEvents, keySpan);
20601
+ this._parseAnimationEvent(name, expression, sourceSpan, handlerSpan, targetEvents, keySpan);
20305
20602
  } else {
20306
20603
  this._parseRegularEvent(name, expression, isAssignmentEvent, sourceSpan, handlerSpan, targetMatchableAttrs, targetEvents, keySpan);
20307
20604
  }
@@ -20310,11 +20607,11 @@ var BindingParser = class {
20310
20607
  const prop = this._schemaRegistry.getMappedPropName(propName);
20311
20608
  return calcPossibleSecurityContexts(this._schemaRegistry, selector, prop, isAttribute);
20312
20609
  }
20313
- _parseAnimationEvent(name, expression, isAssignmentEvent, sourceSpan, handlerSpan, targetEvents, keySpan) {
20610
+ _parseAnimationEvent(name, expression, sourceSpan, handlerSpan, targetEvents, keySpan) {
20314
20611
  const matches = splitAtPeriod(name, [name, ""]);
20315
20612
  const eventName = matches[0];
20316
20613
  const phase = matches[1].toLowerCase();
20317
- const ast = this._parseAction(expression, isAssignmentEvent, handlerSpan);
20614
+ const ast = this._parseAction(expression, handlerSpan);
20318
20615
  targetEvents.push(new ParsedEvent(eventName, phase, 1, ast, sourceSpan, handlerSpan, keySpan));
20319
20616
  if (eventName.length === 0) {
20320
20617
  this._reportError(`Animation event name is missing in binding`, sourceSpan);
@@ -20329,15 +20626,20 @@ var BindingParser = class {
20329
20626
  }
20330
20627
  _parseRegularEvent(name, expression, isAssignmentEvent, sourceSpan, handlerSpan, targetMatchableAttrs, targetEvents, keySpan) {
20331
20628
  const [target, eventName] = splitAtColon(name, [null, name]);
20332
- const ast = this._parseAction(expression, isAssignmentEvent, handlerSpan);
20629
+ const prevErrorCount = this.errors.length;
20630
+ const ast = this._parseAction(expression, handlerSpan);
20631
+ const isValid = this.errors.length === prevErrorCount;
20333
20632
  targetMatchableAttrs.push([name, ast.source]);
20633
+ if (isAssignmentEvent && isValid && !this._isAllowedAssignmentEvent(ast)) {
20634
+ this._reportError("Unsupported expression in a two-way binding", sourceSpan);
20635
+ }
20334
20636
  targetEvents.push(new ParsedEvent(eventName, target, isAssignmentEvent ? 2 : 0, ast, sourceSpan, handlerSpan, keySpan));
20335
20637
  }
20336
- _parseAction(value, isAssignmentEvent, sourceSpan) {
20638
+ _parseAction(value, sourceSpan) {
20337
20639
  const sourceInfo = (sourceSpan && sourceSpan.start || "(unknown").toString();
20338
20640
  const absoluteOffset = sourceSpan && sourceSpan.start ? sourceSpan.start.offset : 0;
20339
20641
  try {
20340
- const ast = this._exprParser.parseAction(value, isAssignmentEvent, sourceInfo, absoluteOffset, this._interpolationConfig);
20642
+ const ast = this._exprParser.parseAction(value, sourceInfo, absoluteOffset, this._interpolationConfig);
20341
20643
  if (ast) {
20342
20644
  this._reportExpressionParserErrors(ast.errors, sourceSpan);
20343
20645
  }
@@ -20365,6 +20667,21 @@ var BindingParser = class {
20365
20667
  this._reportError(report.msg, sourceSpan, ParseErrorLevel.ERROR);
20366
20668
  }
20367
20669
  }
20670
+ _isAllowedAssignmentEvent(ast) {
20671
+ if (ast instanceof ASTWithSource) {
20672
+ return this._isAllowedAssignmentEvent(ast.ast);
20673
+ }
20674
+ if (ast instanceof NonNullAssert) {
20675
+ return this._isAllowedAssignmentEvent(ast.expression);
20676
+ }
20677
+ if (ast instanceof PropertyRead || ast instanceof KeyedRead) {
20678
+ return true;
20679
+ }
20680
+ if (ast instanceof Binary) {
20681
+ return (ast.operation === "&&" || ast.operation === "||" || ast.operation === "??") && (ast.right instanceof PropertyRead || ast.right instanceof KeyedRead);
20682
+ }
20683
+ return ast instanceof Conditional || ast instanceof PrefixNot;
20684
+ }
20368
20685
  };
20369
20686
  function isAnimationLabel(name) {
20370
20687
  return name[0] == "@";
@@ -21529,7 +21846,7 @@ var HtmlAstToIvyAst = class {
21529
21846
  }
21530
21847
  parseAssignmentEvent(name, expression, sourceSpan, valueSpan, targetMatchableAttrs, boundEvents, keySpan) {
21531
21848
  const events = [];
21532
- this.bindingParser.parseEvent(`${name}Change`, `${expression} =$event`, true, sourceSpan, valueSpan || sourceSpan, targetMatchableAttrs, events, keySpan);
21849
+ this.bindingParser.parseEvent(`${name}Change`, expression, true, sourceSpan, valueSpan || sourceSpan, targetMatchableAttrs, events, keySpan);
21533
21850
  addEvents(events, boundEvents);
21534
21851
  }
21535
21852
  reportError(message, sourceSpan, level = ParseErrorLevel.ERROR) {
@@ -22102,7 +22419,7 @@ function prepareEventListenerParameters(eventAst, handlerName = null, scope = nu
22102
22419
  const eventArgumentName = "$event";
22103
22420
  const implicitReceiverAccesses = /* @__PURE__ */ new Set();
22104
22421
  const implicitReceiverExpr = scope === null || scope.bindingLevel === 0 ? variable(CONTEXT_NAME) : scope.getOrCreateSharedContextVar(0);
22105
- const bindingStatements = convertActionBinding(scope, implicitReceiverExpr, handler, "b", eventAst.handlerSpan, implicitReceiverAccesses, EVENT_BINDING_SCOPE_GLOBALS);
22422
+ const bindingStatements = eventAst.type === 2 ? convertAssignmentActionBinding(scope, implicitReceiverExpr, handler, "b", eventAst.handlerSpan, implicitReceiverAccesses, EVENT_BINDING_SCOPE_GLOBALS) : convertActionBinding(scope, implicitReceiverExpr, handler, "b", eventAst.handlerSpan, implicitReceiverAccesses, EVENT_BINDING_SCOPE_GLOBALS);
22106
22423
  const statements = [];
22107
22424
  const variableDeclarations = scope == null ? void 0 : scope.variableDeclarations();
22108
22425
  const restoreViewStatement = scope == null ? void 0 : scope.restoreViewStatement();
@@ -22528,7 +22845,7 @@ var TemplateDefinitionBuilder = class {
22528
22845
  }
22529
22846
  if (element2.outputs.length > 0) {
22530
22847
  for (const outputAst of element2.outputs) {
22531
- this.creationInstruction(outputAst.sourceSpan, Identifiers.listener, this.prepareListenerParameter(element2.name, outputAst, elementIndex));
22848
+ this.creationInstruction(outputAst.sourceSpan, outputAst.type === 2 ? Identifiers.twoWayListener : Identifiers.listener, this.prepareListenerParameter(element2.name, outputAst, elementIndex));
22532
22849
  }
22533
22850
  }
22534
22851
  if (isI18nRootElement) {
@@ -22552,6 +22869,7 @@ var TemplateDefinitionBuilder = class {
22552
22869
  this.allocateBindingSlots(value);
22553
22870
  propertyBindings.push({
22554
22871
  span: input.sourceSpan,
22872
+ reference: Identifiers.property,
22555
22873
  paramsOrFn: getBindingFunctionParams(() => hasValue ? this.convertPropertyBinding(value) : emptyValueBindInstruction, prepareSyntheticPropertyName(input.name))
22556
22874
  });
22557
22875
  } else {
@@ -22586,6 +22904,7 @@ var TemplateDefinitionBuilder = class {
22586
22904
  } else {
22587
22905
  propertyBindings.push({
22588
22906
  span: input.sourceSpan,
22907
+ reference: inputType === 5 ? Identifiers.twoWayProperty : Identifiers.property,
22589
22908
  paramsOrFn: getBindingFunctionParams(() => this.convertPropertyBinding(value), attrName, params)
22590
22909
  });
22591
22910
  }
@@ -22613,7 +22932,7 @@ var TemplateDefinitionBuilder = class {
22613
22932
  }
22614
22933
  });
22615
22934
  for (const propertyBinding of propertyBindings) {
22616
- this.updateInstructionWithAdvance(elementIndex, propertyBinding.span, Identifiers.property, propertyBinding.paramsOrFn);
22935
+ this.updateInstructionWithAdvance(elementIndex, propertyBinding.span, propertyBinding.reference, propertyBinding.paramsOrFn);
22617
22936
  }
22618
22937
  for (const attributeBinding of attributeBindings) {
22619
22938
  this.updateInstructionWithAdvance(elementIndex, attributeBinding.span, Identifiers.attribute, attributeBinding.paramsOrFn);
@@ -22643,7 +22962,7 @@ var TemplateDefinitionBuilder = class {
22643
22962
  }
22644
22963
  }
22645
22964
  const contextName = `${this.contextName}${contextNameSuffix}_${index}`;
22646
- const name = `${contextName}_Template`;
22965
+ const name = this.constantPool.uniqueName(`${contextName}_Template`, false);
22647
22966
  const visitor = new TemplateDefinitionBuilder(this.constantPool, this._bindingScope, this.level + 1, contextName, this.i18n, index, name, this._namespace, this.fileBasedI18nSuffix, this.i18nUseExternalIds, this.deferBlocks, this.elementLocations, this.allDeferrableDepsFn, this._constants);
22648
22967
  this._nestedTemplateFns.push(() => {
22649
22968
  const templateFunctionExpr = visitor.buildTemplateFunction(children, variables, this._ngContentReservedSlots.length + this._ngContentSelectorsOffset, i18nMeta, variableAliases);
@@ -22689,7 +23008,7 @@ var TemplateDefinitionBuilder = class {
22689
23008
  this.templatePropertyBindings(templateIndex, inputs);
22690
23009
  }
22691
23010
  for (const outputAst of template2.outputs) {
22692
- this.creationInstruction(outputAst.sourceSpan, Identifiers.listener, this.prepareListenerParameter("ng_template", outputAst, templateIndex));
23011
+ this.creationInstruction(outputAst.sourceSpan, outputAst.type === 2 ? Identifiers.twoWayListener : Identifiers.listener, this.prepareListenerParameter("ng_template", outputAst, templateIndex));
22693
23012
  }
22694
23013
  }
22695
23014
  }
@@ -22852,7 +23171,10 @@ var TemplateDefinitionBuilder = class {
22852
23171
  const dependencyExp = [];
22853
23172
  for (const deferredDep of metadata.deps) {
22854
23173
  if (deferredDep.isDeferrable) {
22855
- const innerFn = arrowFn([new FnParam("m", DYNAMIC_TYPE)], variable("m").prop(deferredDep.symbolName));
23174
+ const innerFn = arrowFn(
23175
+ [new FnParam("m", DYNAMIC_TYPE)],
23176
+ variable("m").prop(deferredDep.isDefaultImport ? "default" : deferredDep.symbolName)
23177
+ );
22856
23178
  const importExpr2 = new DynamicImportExpr(deferredDep.importPath).prop("then").callFn([innerFn]);
22857
23179
  dependencyExp.push(importExpr2);
22858
23180
  } else {
@@ -23966,8 +24288,8 @@ function compileDirectiveFromMetadata(meta, constantPool, bindingParser) {
23966
24288
  }
23967
24289
  function createDeferredDepsFunction(constantPool, name, deps) {
23968
24290
  const dependencyExp = [];
23969
- for (const [symbolName, importPath] of deps) {
23970
- const innerFn = arrowFn([new FnParam("m", DYNAMIC_TYPE)], variable("m").prop(symbolName));
24291
+ for (const [symbolName, { importPath, isDefaultImport }] of deps) {
24292
+ const innerFn = arrowFn([new FnParam("m", DYNAMIC_TYPE)], variable("m").prop(isDefaultImport ? "default" : symbolName));
23971
24293
  const importExpr2 = new DynamicImportExpr(importPath).prop("then").callFn([innerFn]);
23972
24294
  dependencyExp.push(importExpr2);
23973
24295
  }
@@ -25670,7 +25992,7 @@ function publishFacade(global) {
25670
25992
  }
25671
25993
 
25672
25994
  // bazel-out/k8-fastbuild/bin/packages/compiler/src/version.mjs
25673
- var VERSION2 = new Version("17.2.0-next.1");
25995
+ var VERSION2 = new Version("17.2.0-rc.1");
25674
25996
 
25675
25997
  // bazel-out/k8-fastbuild/bin/packages/compiler/src/i18n/extractor_merger.mjs
25676
25998
  var _VisitorMode;