@player-ui/async-node-plugin 0.12.1-next.0 → 0.13.0-next.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.
@@ -1184,12 +1184,61 @@ var AsyncNodePlugin = function() {
1184
1184
  };
1185
1185
  }
1186
1186
  };
1187
+ var isPromiseLike = function isPromiseLike(value) {
1188
+ var // Check for standard Promise constructor name
1189
+ _value_constructor;
1190
+ return value != null && typeof value === "object" && typeof value.then === "function" && // Additional safeguards against false positives
1191
+ (_instanceof(value, Promise) || ((_value_constructor = value.constructor) === null || _value_constructor === void 0 ? void 0 : _value_constructor.name) === "Promise" || // Verify it has other Promise-like methods to reduce false positives
1192
+ typeof value.catch === "function" && typeof value.finally === "function");
1193
+ };
1194
+ var isAwaitable = function isAwaitable(val) {
1195
+ return isPromiseLike(val) && val[AwaitableSymbol] !== void 0;
1196
+ };
1197
+ var collateAwaitable = function collateAwaitable(promises) {
1198
+ var result = Promise.all(promises);
1199
+ return makeAwaitable(result);
1200
+ };
1187
1201
  var isObjectExpression = function isObjectExpression(expr) {
1188
1202
  if (isExpressionNode(expr)) {
1189
1203
  return false;
1190
1204
  }
1191
1205
  return typeof expr === "object" && expr !== null && !Array.isArray(expr) && "value" in expr;
1192
1206
  };
1207
+ var makePromiseAwareBinaryOp = function makePromiseAwareBinaryOp(operation) {
1208
+ return function(a, b, async) {
1209
+ if (async && (isAwaitable(a) || isAwaitable(b))) {
1210
+ return collateAwaitable([
1211
+ Promise.resolve(a),
1212
+ Promise.resolve(b)
1213
+ ]).awaitableThen(function(param) {
1214
+ var _param = _sliced_to_array(param, 2), resolvedA = _param[0], resolvedB = _param[1];
1215
+ return operation(resolvedA, resolvedB);
1216
+ });
1217
+ }
1218
+ return operation(a, b);
1219
+ };
1220
+ };
1221
+ var makePromiseAwareUnaryOp = function makePromiseAwareUnaryOp(operation) {
1222
+ return function(a, async) {
1223
+ if (async && isAwaitable(a)) {
1224
+ return a.awaitableThen(function(resolved) {
1225
+ return operation(resolved);
1226
+ });
1227
+ }
1228
+ return operation(a);
1229
+ };
1230
+ };
1231
+ var handleConditionalBranching = function handleConditionalBranching(testValue, getTrueBranch, getFalseBranch, resolveNode, async) {
1232
+ if (async && isAwaitable(testValue)) {
1233
+ return testValue.awaitableThen(function(resolved) {
1234
+ var branch2 = resolved ? getTrueBranch() : getFalseBranch();
1235
+ var branchResult = resolveNode(branch2);
1236
+ return isAwaitable(branchResult) ? Promise.resolve(branchResult) : branchResult;
1237
+ });
1238
+ }
1239
+ var branch = testValue ? getTrueBranch() : getFalseBranch();
1240
+ return resolveNode(branch);
1241
+ };
1193
1242
  var parse2 = function parse2(schema) {
1194
1243
  var _loop = function() {
1195
1244
  var next = parseQueue.shift();
@@ -3579,8 +3628,19 @@ var AsyncNodePlugin = function() {
3579
3628
  },
3580
3629
  setDataVal: function() {
3581
3630
  return setDataVal;
3631
+ },
3632
+ waitFor: function() {
3633
+ return waitFor;
3582
3634
  }
3583
3635
  });
3636
+ var AwaitableSymbol = Symbol("Awaitable");
3637
+ function makeAwaitable(promise) {
3638
+ promise[AwaitableSymbol] = AwaitableSymbol;
3639
+ promise.awaitableThen = function(arg) {
3640
+ return makeAwaitable(promise.then(arg));
3641
+ };
3642
+ return promise;
3643
+ }
3584
3644
  var setDataVal = function(_context, binding, value) {
3585
3645
  _context.model.set([
3586
3646
  [
@@ -3596,8 +3656,19 @@ var AsyncNodePlugin = function() {
3596
3656
  return _context.model.delete(binding);
3597
3657
  };
3598
3658
  var conditional = function(ctx, condition, ifTrue, ifFalse) {
3599
- var resolution = ctx.evaluate(condition);
3600
- if (resolution) {
3659
+ var testResult = ctx.evaluate(condition);
3660
+ if (isAwaitable(testResult)) {
3661
+ return testResult.awaitableThen(function(resolvedTest) {
3662
+ if (resolvedTest) {
3663
+ return ctx.evaluate(ifTrue);
3664
+ }
3665
+ if (ifFalse) {
3666
+ return ctx.evaluate(ifFalse);
3667
+ }
3668
+ return null;
3669
+ });
3670
+ }
3671
+ if (testResult) {
3601
3672
  return ctx.evaluate(ifTrue);
3602
3673
  }
3603
3674
  if (ifFalse) {
@@ -3606,12 +3677,15 @@ var AsyncNodePlugin = function() {
3606
3677
  return null;
3607
3678
  };
3608
3679
  conditional.resolveParams = false;
3609
- var andandOperator = function(ctx, a, b) {
3610
- return ctx.evaluate(a) && ctx.evaluate(b);
3680
+ var waitFor = function(ctx, promise) {
3681
+ return makeAwaitable(promise);
3682
+ };
3683
+ var andandOperator = function(ctx, a, b, async) {
3684
+ return LogicalOperators.and(ctx, a, b, async);
3611
3685
  };
3612
3686
  andandOperator.resolveParams = false;
3613
- var ororOperator = function(ctx, a, b) {
3614
- return ctx.evaluate(a) || ctx.evaluate(b);
3687
+ var ororOperator = function(ctx, a, b, async) {
3688
+ return LogicalOperators.or(ctx, a, b, async);
3615
3689
  };
3616
3690
  ororOperator.resolveParams = false;
3617
3691
  var DEFAULT_BINARY_OPERATORS = {
@@ -3631,34 +3705,35 @@ var AsyncNodePlugin = function() {
3631
3705
  "%": function(a, b) {
3632
3706
  return a % b;
3633
3707
  },
3708
+ // Promise-aware comparison operators
3634
3709
  // eslint-disable-next-line
3635
- "==": function(a, b) {
3710
+ "==": makePromiseAwareBinaryOp(function(a, b) {
3636
3711
  return a == b;
3637
- },
3712
+ }),
3638
3713
  // eslint-disable-next-line
3639
- "!=": function(a, b) {
3714
+ "!=": makePromiseAwareBinaryOp(function(a, b) {
3640
3715
  return a != b;
3641
- },
3642
- ">": function(a, b) {
3716
+ }),
3717
+ ">": makePromiseAwareBinaryOp(function(a, b) {
3643
3718
  return a > b;
3644
- },
3645
- ">=": function(a, b) {
3719
+ }),
3720
+ ">=": makePromiseAwareBinaryOp(function(a, b) {
3646
3721
  return a >= b;
3647
- },
3648
- "<": function(a, b) {
3722
+ }),
3723
+ "<": makePromiseAwareBinaryOp(function(a, b) {
3649
3724
  return a < b;
3650
- },
3651
- "<=": function(a, b) {
3725
+ }),
3726
+ "<=": makePromiseAwareBinaryOp(function(a, b) {
3652
3727
  return a <= b;
3653
- },
3654
- "&&": andandOperator,
3655
- "||": ororOperator,
3656
- "!==": function(a, b) {
3728
+ }),
3729
+ "!==": makePromiseAwareBinaryOp(function(a, b) {
3657
3730
  return a !== b;
3658
- },
3659
- "===": function(a, b) {
3731
+ }),
3732
+ "===": makePromiseAwareBinaryOp(function(a, b) {
3660
3733
  return a === b;
3661
- },
3734
+ }),
3735
+ "&&": andandOperator,
3736
+ "||": ororOperator,
3662
3737
  // eslint-disable-next-line
3663
3738
  "|": function(a, b) {
3664
3739
  return a | b;
@@ -3689,8 +3764,73 @@ var AsyncNodePlugin = function() {
3689
3764
  "+": function(a) {
3690
3765
  return Number(a);
3691
3766
  },
3692
- "!": function(a) {
3767
+ "!": makePromiseAwareUnaryOp(function(a) {
3693
3768
  return !a;
3769
+ })
3770
+ };
3771
+ var PromiseCollectionHandler = {
3772
+ /**
3773
+ * Handle array with potential Promise elements
3774
+ */ handleArray: function handleArray(items, async) {
3775
+ if (!async) {
3776
+ return items;
3777
+ }
3778
+ var hasPromises = items.some(function(item) {
3779
+ return isAwaitable(item);
3780
+ });
3781
+ return hasPromises ? collateAwaitable(items) : items;
3782
+ },
3783
+ /**
3784
+ * Handle object with potential Promise keys/values
3785
+ */ handleObject: function handleObject(attributes, resolveNode, async) {
3786
+ var resolvedAttributes = {};
3787
+ var promises = [];
3788
+ var hasPromises = false;
3789
+ attributes.forEach(function(attr) {
3790
+ var key = resolveNode(attr.key);
3791
+ var value = resolveNode(attr.value);
3792
+ if (async && (isAwaitable(key) || isAwaitable(value))) {
3793
+ hasPromises = true;
3794
+ var keyPromise = Promise.resolve(key);
3795
+ var valuePromise = Promise.resolve(value);
3796
+ promises.push(collateAwaitable([
3797
+ keyPromise,
3798
+ valuePromise
3799
+ ]).awaitableThen(function(param) {
3800
+ var _param = _sliced_to_array(param, 2), resolvedKey = _param[0], resolvedValue = _param[1];
3801
+ resolvedAttributes[resolvedKey] = resolvedValue;
3802
+ }));
3803
+ } else {
3804
+ resolvedAttributes[key] = value;
3805
+ }
3806
+ });
3807
+ return hasPromises ? collateAwaitable(promises).awaitableThen(function() {
3808
+ return resolvedAttributes;
3809
+ }) : resolvedAttributes;
3810
+ }
3811
+ };
3812
+ var LogicalOperators = {
3813
+ and: function(ctx, leftNode, rightNode, async) {
3814
+ var leftResult = ctx.evaluate(leftNode);
3815
+ if (async && isAwaitable(leftResult)) {
3816
+ return leftResult.awaitableThen(function(awaitedLeft) {
3817
+ if (!awaitedLeft) return awaitedLeft;
3818
+ var rightResult = ctx.evaluate(rightNode);
3819
+ return isAwaitable(rightResult) ? rightResult : Promise.resolve(rightResult);
3820
+ });
3821
+ }
3822
+ return leftResult && ctx.evaluate(rightNode);
3823
+ },
3824
+ or: function(ctx, leftNode, rightNode, async) {
3825
+ var leftResult = ctx.evaluate(leftNode);
3826
+ if (async && isAwaitable(leftResult)) {
3827
+ return leftResult.awaitableThen(function(awaitedLeft) {
3828
+ if (awaitedLeft) return awaitedLeft;
3829
+ var rightResult = ctx.evaluate(rightNode);
3830
+ return isAwaitable(rightResult) ? rightResult : Promise.resolve(rightResult);
3831
+ });
3832
+ }
3833
+ return leftResult || ctx.evaluate(rightNode);
3694
3834
  }
3695
3835
  };
3696
3836
  var ExpressionEvaluator = /*#__PURE__*/ function() {
@@ -3711,7 +3851,12 @@ var AsyncNodePlugin = function() {
3711
3851
  this.operators = {
3712
3852
  binary: new Map(Object.entries(DEFAULT_BINARY_OPERATORS)),
3713
3853
  unary: new Map(Object.entries(DEFAULT_UNARY_OPERATORS)),
3714
- expressions: new Map(Object.entries(evaluator_functions_exports))
3854
+ expressions: new Map(_to_consumable_array(Object.entries(evaluator_functions_exports)).concat([
3855
+ [
3856
+ "await",
3857
+ waitFor
3858
+ ]
3859
+ ]))
3715
3860
  };
3716
3861
  this.defaultHookOptions = _object_spread_props(_object_spread({}, defaultOptions), {
3717
3862
  evaluate: function(expr) {
@@ -3721,7 +3866,9 @@ var AsyncNodePlugin = function() {
3721
3866
  return _this._execAST(node, _this.defaultHookOptions);
3722
3867
  }
3723
3868
  });
3724
- this.hooks.resolve.tap("ExpressionEvaluator", this._resolveNode.bind(this));
3869
+ this.hooks.resolve.tap("ExpressionEvaluator", function(result, node, options) {
3870
+ return _this._resolveNode(result, node, options);
3871
+ });
3725
3872
  this.evaluate = this.evaluate.bind(this);
3726
3873
  }
3727
3874
  _create_class(ExpressionEvaluator, [
@@ -3759,6 +3906,38 @@ var AsyncNodePlugin = function() {
3759
3906
  return this._execString(String(expression), resolvedOpts);
3760
3907
  }
3761
3908
  },
3909
+ {
3910
+ /**
3911
+ * Evaluate functions in an async context
3912
+ * @experimental These Player APIs are in active development and may change. Use with caution
3913
+ */ key: "evaluateAsync",
3914
+ value: function evaluateAsync(expr, options) {
3915
+ if (Array.isArray(expr)) {
3916
+ var _this = this;
3917
+ return collateAwaitable(expr.map(function() {
3918
+ var _ref = _async_to_generator(function(exp) {
3919
+ return _ts_generator(this, function(_state) {
3920
+ return [
3921
+ 2,
3922
+ _this.evaluate(exp, _object_spread_props(_object_spread({}, options), {
3923
+ async: true
3924
+ }))
3925
+ ];
3926
+ });
3927
+ });
3928
+ return function(exp) {
3929
+ return _ref.apply(this, arguments);
3930
+ };
3931
+ }())).awaitableThen(function(values) {
3932
+ return values.pop();
3933
+ });
3934
+ } else {
3935
+ return this.evaluate(expr, _object_spread_props(_object_spread({}, options), {
3936
+ async: true
3937
+ }));
3938
+ }
3939
+ }
3940
+ },
3762
3941
  {
3763
3942
  key: "addExpressionFunction",
3764
3943
  value: function addExpressionFunction(name, handler) {
@@ -3804,8 +3983,10 @@ var AsyncNodePlugin = function() {
3804
3983
  var matches = exp.match(/^@\[(.*)\]@$/);
3805
3984
  var matchedExp = exp;
3806
3985
  if (matches) {
3807
- var ref;
3808
- ref = _sliced_to_array(Array.from(matches), 2), matchedExp = ref[1], ref;
3986
+ var _Array_from = _sliced_to_array(Array.from(matches), 2), matched = _Array_from[1];
3987
+ if (matched) {
3988
+ matchedExp = matched;
3989
+ }
3809
3990
  }
3810
3991
  var storedAST;
3811
3992
  try {
@@ -3834,6 +4015,8 @@ var AsyncNodePlugin = function() {
3834
4015
  value: function _resolveNode(_currentValue, node, options) {
3835
4016
  var _this = this;
3836
4017
  var resolveNode = options.resolveNode, model = options.model;
4018
+ var _options_async;
4019
+ var isAsync = (_options_async = options.async) !== null && _options_async !== void 0 ? _options_async : false;
3837
4020
  var expressionContext = _object_spread_props(_object_spread({}, options), {
3838
4021
  evaluate: function(expr) {
3839
4022
  return _this.evaluate(expr, options);
@@ -3853,11 +4036,33 @@ var AsyncNodePlugin = function() {
3853
4036
  if (operator) {
3854
4037
  if ("resolveParams" in operator) {
3855
4038
  if (operator.resolveParams === false) {
3856
- return operator(expressionContext, node.left, node.right);
4039
+ return operator(expressionContext, node.left, node.right, isAsync);
3857
4040
  }
3858
- return operator(expressionContext, resolveNode(node.left), resolveNode(node.right));
4041
+ var left2 = resolveNode(node.left);
4042
+ var right2 = resolveNode(node.right);
4043
+ if (options.async && (isAwaitable(left2) || isAwaitable(right2))) {
4044
+ return collateAwaitable([
4045
+ left2,
4046
+ right2
4047
+ ]).awaitableThen(function(param) {
4048
+ var _param = _sliced_to_array(param, 2), leftVal = _param[0], rightVal = _param[1];
4049
+ return operator(expressionContext, leftVal, rightVal, isAsync);
4050
+ });
4051
+ }
4052
+ return operator(expressionContext, left2, right2, isAsync);
3859
4053
  }
3860
- return operator(resolveNode(node.left), resolveNode(node.right));
4054
+ var left = resolveNode(node.left);
4055
+ var right = resolveNode(node.right);
4056
+ if (options.async && (isAwaitable(left) || isAwaitable(right))) {
4057
+ return collateAwaitable([
4058
+ left,
4059
+ right
4060
+ ]).awaitableThen(function(param) {
4061
+ var _param = _sliced_to_array(param, 2), leftVal = _param[0], rightVal = _param[1];
4062
+ return operator(leftVal, rightVal, isAsync);
4063
+ });
4064
+ }
4065
+ return operator(left, right, isAsync);
3861
4066
  }
3862
4067
  return;
3863
4068
  }
@@ -3865,21 +4070,29 @@ var AsyncNodePlugin = function() {
3865
4070
  var operator1 = this.operators.unary.get(node.operator);
3866
4071
  if (operator1) {
3867
4072
  if ("resolveParams" in operator1) {
3868
- return operator1(expressionContext, operator1.resolveParams === false ? node.argument : resolveNode(node.argument));
4073
+ if (operator1.resolveParams === false) {
4074
+ return operator1(expressionContext, node.argument, isAsync);
4075
+ }
4076
+ var arg2 = resolveNode(node.argument);
4077
+ if (options.async && isAwaitable(arg2)) {
4078
+ return arg2.awaitableThen(function(argVal) {
4079
+ return operator1(expressionContext, argVal, isAsync);
4080
+ });
4081
+ }
4082
+ return operator1(expressionContext, arg2, isAsync);
3869
4083
  }
3870
- return operator1(resolveNode(node.argument));
4084
+ var arg = resolveNode(node.argument);
4085
+ if (options.async && isAwaitable(arg)) {
4086
+ return arg.awaitableThen(function(argVal) {
4087
+ return operator1(argVal, isAsync);
4088
+ });
4089
+ }
4090
+ return operator1(arg, isAsync);
3871
4091
  }
3872
4092
  return;
3873
4093
  }
3874
4094
  if (node.type === "Object") {
3875
- var attributes = node.attributes;
3876
- var resolvedAttributes = {};
3877
- attributes.forEach(function(attr) {
3878
- var key = resolveNode(attr.key);
3879
- var value = resolveNode(attr.value);
3880
- resolvedAttributes[key] = value;
3881
- });
3882
- return resolvedAttributes;
4095
+ return PromiseCollectionHandler.handleObject(node.attributes, resolveNode, options.async || false);
3883
4096
  }
3884
4097
  if (node.type === "CallExpression") {
3885
4098
  var expressionName = node.callTarget.name;
@@ -3887,6 +4100,9 @@ var AsyncNodePlugin = function() {
3887
4100
  if (!operator2) {
3888
4101
  throw new Error("Unknown expression function: ".concat(expressionName));
3889
4102
  }
4103
+ if (operator2.name === waitFor.name && !options.async) {
4104
+ throw new Error("Usage of await outside of async context");
4105
+ }
3890
4106
  if ("resolveParams" in operator2 && operator2.resolveParams === false) {
3891
4107
  return operator2.apply(void 0, [
3892
4108
  expressionContext
@@ -3895,6 +4111,16 @@ var AsyncNodePlugin = function() {
3895
4111
  var args = node.args.map(function(n) {
3896
4112
  return resolveNode(n);
3897
4113
  });
4114
+ if (options.async) {
4115
+ var hasPromises = args.some(isAwaitable);
4116
+ if (hasPromises) {
4117
+ return collateAwaitable(args).awaitableThen(function(resolvedArgs) {
4118
+ return operator2.apply(void 0, [
4119
+ expressionContext
4120
+ ].concat(_to_consumable_array(resolvedArgs)));
4121
+ });
4122
+ }
4123
+ }
3898
4124
  return operator2.apply(void 0, [
3899
4125
  expressionContext
3900
4126
  ].concat(_to_consumable_array(args)));
@@ -3909,11 +4135,36 @@ var AsyncNodePlugin = function() {
3909
4135
  if (node.type === "MemberExpression") {
3910
4136
  var obj = resolveNode(node.object);
3911
4137
  var prop = resolveNode(node.property);
4138
+ if (options.async && (isAwaitable(obj) || isAwaitable(prop))) {
4139
+ return collateAwaitable([
4140
+ obj,
4141
+ prop
4142
+ ]).awaitableThen(function(param) {
4143
+ var _param = _sliced_to_array(param, 2), objVal = _param[0], propVal = _param[1];
4144
+ return objVal[propVal];
4145
+ });
4146
+ }
3912
4147
  return obj[prop];
3913
4148
  }
3914
4149
  if (node.type === "Assignment") {
3915
4150
  if (node.left.type === "ModelRef") {
3916
4151
  var value = resolveNode(node.right);
4152
+ if (isPromiseLike(value)) {
4153
+ if (options.async && isAwaitable(value)) {
4154
+ return value.awaitableThen(function(resolvedValue) {
4155
+ model.set([
4156
+ [
4157
+ node.left.ref,
4158
+ resolvedValue
4159
+ ]
4160
+ ]);
4161
+ return resolvedValue;
4162
+ });
4163
+ } else {
4164
+ var _options_logger;
4165
+ (_options_logger = options.logger) === null || _options_logger === void 0 ? void 0 : _options_logger.warn("Unawaited promise written to mode, this behavior is undefined and may change in future releases");
4166
+ }
4167
+ }
3917
4168
  model.set([
3918
4169
  [
3919
4170
  node.left.ref,
@@ -3924,19 +4175,30 @@ var AsyncNodePlugin = function() {
3924
4175
  }
3925
4176
  if (node.left.type === "Identifier") {
3926
4177
  var value1 = resolveNode(node.right);
4178
+ if (options.async && isAwaitable(value1)) {
4179
+ return value1.awaitableThen(function(resolvedValue) {
4180
+ _this.vars[node.left.name] = resolvedValue;
4181
+ return resolvedValue;
4182
+ });
4183
+ }
3927
4184
  this.vars[node.left.name] = value1;
3928
4185
  return value1;
3929
4186
  }
3930
4187
  return;
3931
4188
  }
3932
4189
  if (node.type === "ConditionalExpression") {
3933
- var result = resolveNode(node.test) ? node.consequent : node.alternate;
3934
- return resolveNode(result);
4190
+ var testResult = resolveNode(node.test);
4191
+ return handleConditionalBranching(testResult, function() {
4192
+ return node.consequent;
4193
+ }, function() {
4194
+ return node.alternate;
4195
+ }, resolveNode, isAsync);
3935
4196
  }
3936
4197
  if (node.type === "ArrayExpression") {
3937
- return node.elements.map(function(ele) {
4198
+ var results = node.elements.map(function(ele) {
3938
4199
  return resolveNode(ele);
3939
4200
  });
4201
+ return PromiseCollectionHandler.handleArray(results, isAsync);
3940
4202
  }
3941
4203
  if (node.type === "Modification") {
3942
4204
  var operation = this.operators.binary.get(node.operator);
@@ -3944,14 +4206,49 @@ var AsyncNodePlugin = function() {
3944
4206
  var newValue;
3945
4207
  if ("resolveParams" in operation) {
3946
4208
  if (operation.resolveParams === false) {
3947
- newValue = operation(expressionContext, node.left, node.right);
4209
+ newValue = operation(expressionContext, node.left, node.right, isAsync);
3948
4210
  } else {
3949
- newValue = operation(expressionContext, resolveNode(node.left), resolveNode(node.right));
4211
+ var left1 = resolveNode(node.left);
4212
+ var right1 = resolveNode(node.right);
4213
+ if (options.async && (isAwaitable(left1) || isAwaitable(right1))) {
4214
+ newValue = collateAwaitable([
4215
+ left1,
4216
+ right1
4217
+ ]).awaitableThen(function(param) {
4218
+ var _param = _sliced_to_array(param, 2), leftVal = _param[0], rightVal = _param[1];
4219
+ return operation(expressionContext, leftVal, rightVal, isAsync);
4220
+ });
4221
+ } else {
4222
+ newValue = operation(expressionContext, left1, right1, isAsync);
4223
+ }
3950
4224
  }
3951
4225
  } else {
3952
- newValue = operation(resolveNode(node.left), resolveNode(node.right));
4226
+ var left3 = resolveNode(node.left);
4227
+ var right3 = resolveNode(node.right);
4228
+ if (options.async && (isAwaitable(left3) || isAwaitable(right3))) {
4229
+ newValue = collateAwaitable([
4230
+ left3,
4231
+ right3
4232
+ ]).awaitableThen(function(param) {
4233
+ var _param = _sliced_to_array(param, 2), leftVal = _param[0], rightVal = _param[1];
4234
+ return operation(leftVal, rightVal, isAsync);
4235
+ });
4236
+ } else {
4237
+ newValue = operation(left3, right3, isAsync);
4238
+ }
3953
4239
  }
3954
4240
  if (node.left.type === "ModelRef") {
4241
+ if (options.async && isAwaitable(newValue)) {
4242
+ return newValue.awaitableThen(function(resolvedValue) {
4243
+ model.set([
4244
+ [
4245
+ node.left.ref,
4246
+ resolvedValue
4247
+ ]
4248
+ ]);
4249
+ return resolvedValue;
4250
+ });
4251
+ }
3955
4252
  model.set([
3956
4253
  [
3957
4254
  node.left.ref,
@@ -3959,6 +4256,12 @@ var AsyncNodePlugin = function() {
3959
4256
  ]
3960
4257
  ]);
3961
4258
  } else if (node.left.type === "Identifier") {
4259
+ if (options.async && isAwaitable(newValue)) {
4260
+ return newValue.awaitableThen(function(resolvedValue) {
4261
+ _this.vars[node.left.name] = resolvedValue;
4262
+ return resolvedValue;
4263
+ });
4264
+ }
3962
4265
  this.vars[node.left.name] = newValue;
3963
4266
  }
3964
4267
  return newValue;
@@ -4837,20 +5140,15 @@ var AsyncNodePlugin = function() {
4837
5140
  }();
4838
5141
  var ViewInstance = /*#__PURE__*/ function() {
4839
5142
  function ViewInstance(initialView, resolverOptions) {
4840
- var _this = this;
4841
5143
  _class_call_check(this, ViewInstance);
4842
5144
  this.hooks = {
4843
5145
  onUpdate: new SyncHook(),
4844
5146
  parser: new SyncHook(),
4845
5147
  resolver: new SyncHook(),
4846
- onTemplatePluginCreated: new SyncHook(),
4847
5148
  templatePlugin: new SyncHook()
4848
5149
  };
4849
5150
  this.initialView = initialView;
4850
5151
  this.resolverOptions = resolverOptions;
4851
- this.hooks.onTemplatePluginCreated.tap("view", function(templatePlugin) {
4852
- _this.templatePlugin = templatePlugin;
4853
- });
4854
5152
  }
4855
5153
  _create_class(ViewInstance, [
4856
5154
  {
@@ -4897,6 +5195,12 @@ var AsyncNodePlugin = function() {
4897
5195
  var _this_validationProvider;
4898
5196
  return (_this_validationProvider = this.validationProvider) === null || _this_validationProvider === void 0 ? void 0 : _this_validationProvider.getValidationsForBinding(binding);
4899
5197
  }
5198
+ },
5199
+ {
5200
+ key: "setTemplatePlugin",
5201
+ value: function setTemplatePlugin(plugin) {
5202
+ this.templatePlugin = plugin;
5203
+ }
4900
5204
  }
4901
5205
  ]);
4902
5206
  return ViewInstance;
@@ -5195,6 +5499,7 @@ var AsyncNodePlugin = function() {
5195
5499
  value: function apply(view) {
5196
5500
  view.hooks.parser.tap("template", this.applyParser.bind(this));
5197
5501
  view.hooks.resolver.tap("template", this.applyResolverHooks.bind(this));
5502
+ view.setTemplatePlugin(this);
5198
5503
  }
5199
5504
  }
5200
5505
  ]);
@@ -6803,8 +7108,7 @@ var AsyncNodePlugin = function() {
6803
7108
  var _this1 = this;
6804
7109
  _class_call_check(this, ViewController);
6805
7110
  this.hooks = {
6806
- /** Do any processing before the `View` instance is created */ resolveView: new SyncWaterfallHook(),
6807
- // The hook right before the View starts resolving. Attach anything custom here
7111
+ resolveView: new SyncWaterfallHook(),
6808
7112
  view: new SyncHook()
6809
7113
  };
6810
7114
  this.transformRegistry = new Registry();
@@ -6852,6 +7156,7 @@ var AsyncNodePlugin = function() {
6852
7156
  ]));
6853
7157
  }
6854
7158
  });
7159
+ this.viewPlugins = this.createViewPlugins();
6855
7160
  }
6856
7161
  _create_class(ViewController, [
6857
7162
  {
@@ -6907,9 +7212,50 @@ var AsyncNodePlugin = function() {
6907
7212
  }
6908
7213
  var view = new ViewInstance(source, this.viewOptions);
6909
7214
  this.currentView = view;
7215
+ this.applyViewPlugins(view);
6910
7216
  this.hooks.view.call(view);
6911
7217
  view.update();
6912
7218
  }
7219
+ },
7220
+ {
7221
+ key: "applyViewPlugins",
7222
+ value: function applyViewPlugins(view) {
7223
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
7224
+ try {
7225
+ for(var _iterator = this.viewPlugins[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
7226
+ var plugin = _step.value;
7227
+ plugin.apply(view);
7228
+ }
7229
+ } catch (err) {
7230
+ _didIteratorError = true;
7231
+ _iteratorError = err;
7232
+ } finally{
7233
+ try {
7234
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
7235
+ _iterator.return();
7236
+ }
7237
+ } finally{
7238
+ if (_didIteratorError) {
7239
+ throw _iteratorError;
7240
+ }
7241
+ }
7242
+ }
7243
+ }
7244
+ },
7245
+ {
7246
+ key: "createViewPlugins",
7247
+ value: function createViewPlugins() {
7248
+ var pluginOptions = toNodeResolveOptions(this.viewOptions);
7249
+ return [
7250
+ new AssetPlugin(),
7251
+ new SwitchPlugin(pluginOptions),
7252
+ new ApplicabilityPlugin(),
7253
+ new AssetTransformCorePlugin(this.transformRegistry),
7254
+ new StringResolverPlugin(),
7255
+ new TemplatePlugin(pluginOptions),
7256
+ new MultiNodePlugin()
7257
+ ];
7258
+ }
6913
7259
  }
6914
7260
  ]);
6915
7261
  return ViewController;
@@ -7282,35 +7628,6 @@ var AsyncNodePlugin = function() {
7282
7628
  ref: Symbol("not-started"),
7283
7629
  status: "not-started"
7284
7630
  };
7285
- var DefaultViewPlugin = /*#__PURE__*/ function() {
7286
- function DefaultViewPlugin() {
7287
- _class_call_check(this, DefaultViewPlugin);
7288
- this.name = "default-view-plugin";
7289
- }
7290
- _create_class(DefaultViewPlugin, [
7291
- {
7292
- key: "apply",
7293
- value: function apply(player) {
7294
- var _this = this;
7295
- player.hooks.viewController.tap(this.name, function(viewController) {
7296
- viewController.hooks.view.tap(_this.name, function(view) {
7297
- var pluginOptions = toNodeResolveOptions(view.resolverOptions);
7298
- new AssetPlugin().apply(view);
7299
- new SwitchPlugin(pluginOptions).apply(view);
7300
- new ApplicabilityPlugin().apply(view);
7301
- new AssetTransformCorePlugin(viewController.transformRegistry).apply(view);
7302
- new StringResolverPlugin().apply(view);
7303
- var templatePlugin = new TemplatePlugin(pluginOptions);
7304
- templatePlugin.apply(view);
7305
- view.hooks.onTemplatePluginCreated.call(templatePlugin);
7306
- new MultiNodePlugin().apply(view);
7307
- });
7308
- });
7309
- }
7310
- }
7311
- ]);
7312
- return DefaultViewPlugin;
7313
- }();
7314
7631
  var PLAYER_VERSION = "__VERSION__";
7315
7632
  var COMMIT = "__GIT_COMMIT__";
7316
7633
  var _Player = /*#__PURE__*/ function() {
@@ -7322,26 +7639,25 @@ var AsyncNodePlugin = function() {
7322
7639
  this.constantsController = new ConstantsController();
7323
7640
  this.state = NOT_STARTED_STATE;
7324
7641
  this.hooks = {
7325
- /** The hook that fires every time we create a new flowController (a new Content blob is passed in) */ flowController: new SyncHook(),
7326
- /** The hook that updates/handles views */ viewController: new SyncHook(),
7327
- /** A hook called every-time there's a new view. This is equivalent to the view hook on the view-controller */ view: new SyncHook(),
7328
- /** Called when an expression evaluator was created */ expressionEvaluator: new SyncHook(),
7329
- /** The hook that creates and manages data */ dataController: new SyncHook(),
7330
- /** Called after the schema is created for a flow */ schema: new SyncHook(),
7331
- /** Manages validations (schema and x-field ) */ validationController: new SyncHook(),
7332
- /** Manages parsing binding */ bindingParser: new SyncHook(),
7333
- /** A that's called for state changes in the flow execution */ state: new SyncHook(),
7334
- /** A hook to access the current flow */ onStart: new SyncHook(),
7335
- /** A hook for when the flow ends either in success or failure */ onEnd: new SyncHook(),
7336
- /** Mutate the Content flow before starting */ resolveFlowContent: new SyncWaterfallHook()
7642
+ flowController: new SyncHook(),
7643
+ viewController: new SyncHook(),
7644
+ view: new SyncHook(),
7645
+ expressionEvaluator: new SyncHook(),
7646
+ dataController: new SyncHook(),
7647
+ schema: new SyncHook(),
7648
+ validationController: new SyncHook(),
7649
+ bindingParser: new SyncHook(),
7650
+ state: new SyncHook(),
7651
+ onStart: new SyncHook(),
7652
+ onEnd: new SyncHook(),
7653
+ resolveFlowContent: new SyncWaterfallHook()
7337
7654
  };
7338
7655
  if (config === null || config === void 0 ? void 0 : config.logger) {
7339
7656
  this.logger.addHandler(config.logger);
7340
7657
  }
7341
7658
  this.config = config || {};
7342
7659
  this.config.plugins = [
7343
- new DefaultExpPlugin(),
7344
- new DefaultViewPlugin()
7660
+ new DefaultExpPlugin()
7345
7661
  ].concat(_to_consumable_array(this.config.plugins || []), [
7346
7662
  new FlowExpPlugin()
7347
7663
  ]);
@@ -7533,10 +7849,90 @@ var AsyncNodePlugin = function() {
7533
7849
  var value = (_flowInstance_currentState = flowInstance.currentState) === null || _flowInstance_currentState === void 0 ? void 0 : _flowInstance_currentState.value;
7534
7850
  if (value && value.state_type === "ACTION") {
7535
7851
  var exp = value.exp;
7536
- flowController === null || flowController === void 0 ? void 0 : flowController.transition(String(expressionEvaluator === null || expressionEvaluator === void 0 ? void 0 : expressionEvaluator.evaluate(exp)));
7852
+ var result = expressionEvaluator.evaluate(exp);
7853
+ if (isPromiseLike(result)) {
7854
+ _this.logger.warn("Async expression used as return value in in non-async context, transitioning with '*' value");
7855
+ }
7856
+ flowController === null || flowController === void 0 ? void 0 : flowController.transition(String(result));
7537
7857
  }
7538
7858
  expressionEvaluator.reset();
7539
7859
  });
7860
+ var _this1 = _this;
7861
+ flow.hooks.afterTransition.tap("player", function() {
7862
+ var _ref = _async_to_generator(function(flowInstance) {
7863
+ var _flowInstance_currentState, value, exp, result, e;
7864
+ return _ts_generator(this, function(_state) {
7865
+ switch(_state.label){
7866
+ case 0:
7867
+ value = (_flowInstance_currentState = flowInstance.currentState) === null || _flowInstance_currentState === void 0 ? void 0 : _flowInstance_currentState.value;
7868
+ if (!(value && value.state_type === "ASYNC_ACTION")) return [
7869
+ 3,
7870
+ 8
7871
+ ];
7872
+ exp = value.exp;
7873
+ _state.label = 1;
7874
+ case 1:
7875
+ _state.trys.push([
7876
+ 1,
7877
+ 7,
7878
+ ,
7879
+ 8
7880
+ ]);
7881
+ result = expressionEvaluator.evaluateAsync(exp);
7882
+ if (!isPromiseLike(result)) return [
7883
+ 3,
7884
+ 5
7885
+ ];
7886
+ if (!value.await) return [
7887
+ 3,
7888
+ 3
7889
+ ];
7890
+ return [
7891
+ 4,
7892
+ result
7893
+ ];
7894
+ case 2:
7895
+ result = _state.sent();
7896
+ return [
7897
+ 3,
7898
+ 4
7899
+ ];
7900
+ case 3:
7901
+ _this1.logger.warn("Unawaited promise used as return value in in non-async context, transitioning with '*' value");
7902
+ _state.label = 4;
7903
+ case 4:
7904
+ return [
7905
+ 3,
7906
+ 6
7907
+ ];
7908
+ case 5:
7909
+ _this1.logger.warn("Non async expression used in async action node");
7910
+ _state.label = 6;
7911
+ case 6:
7912
+ flowController === null || flowController === void 0 ? void 0 : flowController.transition(String(result));
7913
+ return [
7914
+ 3,
7915
+ 8
7916
+ ];
7917
+ case 7:
7918
+ e = _state.sent();
7919
+ flowResultDeferred.reject(e);
7920
+ return [
7921
+ 3,
7922
+ 8
7923
+ ];
7924
+ case 8:
7925
+ expressionEvaluator.reset();
7926
+ return [
7927
+ 2
7928
+ ];
7929
+ }
7930
+ });
7931
+ });
7932
+ return function(flowInstance) {
7933
+ return _ref.apply(this, arguments);
7934
+ };
7935
+ }());
7540
7936
  });
7541
7937
  this.hooks.dataController.call(dataController);
7542
7938
  validationController.setOptions({
@@ -7574,11 +7970,9 @@ var AsyncNodePlugin = function() {
7574
7970
  }),
7575
7971
  constants: this.constantsController
7576
7972
  });
7577
- this.hooks.viewController.tap("player", function(vc) {
7578
- vc.hooks.view.tap("player", function(view) {
7579
- validationController.onView(view);
7580
- _this.hooks.view.call(view);
7581
- });
7973
+ viewController.hooks.view.tap("player", function(view) {
7974
+ validationController.onView(view);
7975
+ _this.hooks.view.call(view);
7582
7976
  });
7583
7977
  this.hooks.viewController.call(viewController);
7584
7978
  return {