@player-ui/beacon-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 BeaconPlugin = 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();
@@ -3596,8 +3645,19 @@ var BeaconPlugin = function() {
3596
3645
  },
3597
3646
  setDataVal: function() {
3598
3647
  return setDataVal;
3648
+ },
3649
+ waitFor: function() {
3650
+ return waitFor;
3599
3651
  }
3600
3652
  });
3653
+ var AwaitableSymbol = Symbol("Awaitable");
3654
+ function makeAwaitable(promise) {
3655
+ promise[AwaitableSymbol] = AwaitableSymbol;
3656
+ promise.awaitableThen = function(arg) {
3657
+ return makeAwaitable(promise.then(arg));
3658
+ };
3659
+ return promise;
3660
+ }
3601
3661
  var setDataVal = function(_context, binding, value) {
3602
3662
  _context.model.set([
3603
3663
  [
@@ -3613,8 +3673,19 @@ var BeaconPlugin = function() {
3613
3673
  return _context.model.delete(binding);
3614
3674
  };
3615
3675
  var conditional = function(ctx, condition, ifTrue, ifFalse) {
3616
- var resolution = ctx.evaluate(condition);
3617
- if (resolution) {
3676
+ var testResult = ctx.evaluate(condition);
3677
+ if (isAwaitable(testResult)) {
3678
+ return testResult.awaitableThen(function(resolvedTest) {
3679
+ if (resolvedTest) {
3680
+ return ctx.evaluate(ifTrue);
3681
+ }
3682
+ if (ifFalse) {
3683
+ return ctx.evaluate(ifFalse);
3684
+ }
3685
+ return null;
3686
+ });
3687
+ }
3688
+ if (testResult) {
3618
3689
  return ctx.evaluate(ifTrue);
3619
3690
  }
3620
3691
  if (ifFalse) {
@@ -3623,12 +3694,15 @@ var BeaconPlugin = function() {
3623
3694
  return null;
3624
3695
  };
3625
3696
  conditional.resolveParams = false;
3626
- var andandOperator = function(ctx, a, b) {
3627
- return ctx.evaluate(a) && ctx.evaluate(b);
3697
+ var waitFor = function(ctx, promise) {
3698
+ return makeAwaitable(promise);
3699
+ };
3700
+ var andandOperator = function(ctx, a, b, async) {
3701
+ return LogicalOperators.and(ctx, a, b, async);
3628
3702
  };
3629
3703
  andandOperator.resolveParams = false;
3630
- var ororOperator = function(ctx, a, b) {
3631
- return ctx.evaluate(a) || ctx.evaluate(b);
3704
+ var ororOperator = function(ctx, a, b, async) {
3705
+ return LogicalOperators.or(ctx, a, b, async);
3632
3706
  };
3633
3707
  ororOperator.resolveParams = false;
3634
3708
  var DEFAULT_BINARY_OPERATORS = {
@@ -3648,34 +3722,35 @@ var BeaconPlugin = function() {
3648
3722
  "%": function(a, b) {
3649
3723
  return a % b;
3650
3724
  },
3725
+ // Promise-aware comparison operators
3651
3726
  // eslint-disable-next-line
3652
- "==": function(a, b) {
3727
+ "==": makePromiseAwareBinaryOp(function(a, b) {
3653
3728
  return a == b;
3654
- },
3729
+ }),
3655
3730
  // eslint-disable-next-line
3656
- "!=": function(a, b) {
3731
+ "!=": makePromiseAwareBinaryOp(function(a, b) {
3657
3732
  return a != b;
3658
- },
3659
- ">": function(a, b) {
3733
+ }),
3734
+ ">": makePromiseAwareBinaryOp(function(a, b) {
3660
3735
  return a > b;
3661
- },
3662
- ">=": function(a, b) {
3736
+ }),
3737
+ ">=": makePromiseAwareBinaryOp(function(a, b) {
3663
3738
  return a >= b;
3664
- },
3665
- "<": function(a, b) {
3739
+ }),
3740
+ "<": makePromiseAwareBinaryOp(function(a, b) {
3666
3741
  return a < b;
3667
- },
3668
- "<=": function(a, b) {
3742
+ }),
3743
+ "<=": makePromiseAwareBinaryOp(function(a, b) {
3669
3744
  return a <= b;
3670
- },
3671
- "&&": andandOperator,
3672
- "||": ororOperator,
3673
- "!==": function(a, b) {
3745
+ }),
3746
+ "!==": makePromiseAwareBinaryOp(function(a, b) {
3674
3747
  return a !== b;
3675
- },
3676
- "===": function(a, b) {
3748
+ }),
3749
+ "===": makePromiseAwareBinaryOp(function(a, b) {
3677
3750
  return a === b;
3678
- },
3751
+ }),
3752
+ "&&": andandOperator,
3753
+ "||": ororOperator,
3679
3754
  // eslint-disable-next-line
3680
3755
  "|": function(a, b) {
3681
3756
  return a | b;
@@ -3706,8 +3781,73 @@ var BeaconPlugin = function() {
3706
3781
  "+": function(a) {
3707
3782
  return Number(a);
3708
3783
  },
3709
- "!": function(a) {
3784
+ "!": makePromiseAwareUnaryOp(function(a) {
3710
3785
  return !a;
3786
+ })
3787
+ };
3788
+ var PromiseCollectionHandler = {
3789
+ /**
3790
+ * Handle array with potential Promise elements
3791
+ */ handleArray: function handleArray(items, async) {
3792
+ if (!async) {
3793
+ return items;
3794
+ }
3795
+ var hasPromises = items.some(function(item) {
3796
+ return isAwaitable(item);
3797
+ });
3798
+ return hasPromises ? collateAwaitable(items) : items;
3799
+ },
3800
+ /**
3801
+ * Handle object with potential Promise keys/values
3802
+ */ handleObject: function handleObject(attributes, resolveNode, async) {
3803
+ var resolvedAttributes = {};
3804
+ var promises = [];
3805
+ var hasPromises = false;
3806
+ attributes.forEach(function(attr) {
3807
+ var key = resolveNode(attr.key);
3808
+ var value = resolveNode(attr.value);
3809
+ if (async && (isAwaitable(key) || isAwaitable(value))) {
3810
+ hasPromises = true;
3811
+ var keyPromise = Promise.resolve(key);
3812
+ var valuePromise = Promise.resolve(value);
3813
+ promises.push(collateAwaitable([
3814
+ keyPromise,
3815
+ valuePromise
3816
+ ]).awaitableThen(function(param) {
3817
+ var _param = _sliced_to_array(param, 2), resolvedKey = _param[0], resolvedValue = _param[1];
3818
+ resolvedAttributes[resolvedKey] = resolvedValue;
3819
+ }));
3820
+ } else {
3821
+ resolvedAttributes[key] = value;
3822
+ }
3823
+ });
3824
+ return hasPromises ? collateAwaitable(promises).awaitableThen(function() {
3825
+ return resolvedAttributes;
3826
+ }) : resolvedAttributes;
3827
+ }
3828
+ };
3829
+ var LogicalOperators = {
3830
+ and: function(ctx, leftNode, rightNode, async) {
3831
+ var leftResult = ctx.evaluate(leftNode);
3832
+ if (async && isAwaitable(leftResult)) {
3833
+ return leftResult.awaitableThen(function(awaitedLeft) {
3834
+ if (!awaitedLeft) return awaitedLeft;
3835
+ var rightResult = ctx.evaluate(rightNode);
3836
+ return isAwaitable(rightResult) ? rightResult : Promise.resolve(rightResult);
3837
+ });
3838
+ }
3839
+ return leftResult && ctx.evaluate(rightNode);
3840
+ },
3841
+ or: function(ctx, leftNode, rightNode, async) {
3842
+ var leftResult = ctx.evaluate(leftNode);
3843
+ if (async && isAwaitable(leftResult)) {
3844
+ return leftResult.awaitableThen(function(awaitedLeft) {
3845
+ if (awaitedLeft) return awaitedLeft;
3846
+ var rightResult = ctx.evaluate(rightNode);
3847
+ return isAwaitable(rightResult) ? rightResult : Promise.resolve(rightResult);
3848
+ });
3849
+ }
3850
+ return leftResult || ctx.evaluate(rightNode);
3711
3851
  }
3712
3852
  };
3713
3853
  var ExpressionEvaluator = /*#__PURE__*/ function() {
@@ -3728,7 +3868,12 @@ var BeaconPlugin = function() {
3728
3868
  this.operators = {
3729
3869
  binary: new Map(Object.entries(DEFAULT_BINARY_OPERATORS)),
3730
3870
  unary: new Map(Object.entries(DEFAULT_UNARY_OPERATORS)),
3731
- expressions: new Map(Object.entries(evaluator_functions_exports))
3871
+ expressions: new Map(_to_consumable_array(Object.entries(evaluator_functions_exports)).concat([
3872
+ [
3873
+ "await",
3874
+ waitFor
3875
+ ]
3876
+ ]))
3732
3877
  };
3733
3878
  this.defaultHookOptions = _object_spread_props(_object_spread({}, defaultOptions), {
3734
3879
  evaluate: function(expr) {
@@ -3738,7 +3883,9 @@ var BeaconPlugin = function() {
3738
3883
  return _this._execAST(node, _this.defaultHookOptions);
3739
3884
  }
3740
3885
  });
3741
- this.hooks.resolve.tap("ExpressionEvaluator", this._resolveNode.bind(this));
3886
+ this.hooks.resolve.tap("ExpressionEvaluator", function(result, node, options) {
3887
+ return _this._resolveNode(result, node, options);
3888
+ });
3742
3889
  this.evaluate = this.evaluate.bind(this);
3743
3890
  }
3744
3891
  _create_class(ExpressionEvaluator, [
@@ -3776,6 +3923,38 @@ var BeaconPlugin = function() {
3776
3923
  return this._execString(String(expression), resolvedOpts);
3777
3924
  }
3778
3925
  },
3926
+ {
3927
+ /**
3928
+ * Evaluate functions in an async context
3929
+ * @experimental These Player APIs are in active development and may change. Use with caution
3930
+ */ key: "evaluateAsync",
3931
+ value: function evaluateAsync(expr, options) {
3932
+ if (Array.isArray(expr)) {
3933
+ var _this = this;
3934
+ return collateAwaitable(expr.map(function() {
3935
+ var _ref = _async_to_generator(function(exp) {
3936
+ return _ts_generator(this, function(_state) {
3937
+ return [
3938
+ 2,
3939
+ _this.evaluate(exp, _object_spread_props(_object_spread({}, options), {
3940
+ async: true
3941
+ }))
3942
+ ];
3943
+ });
3944
+ });
3945
+ return function(exp) {
3946
+ return _ref.apply(this, arguments);
3947
+ };
3948
+ }())).awaitableThen(function(values) {
3949
+ return values.pop();
3950
+ });
3951
+ } else {
3952
+ return this.evaluate(expr, _object_spread_props(_object_spread({}, options), {
3953
+ async: true
3954
+ }));
3955
+ }
3956
+ }
3957
+ },
3779
3958
  {
3780
3959
  key: "addExpressionFunction",
3781
3960
  value: function addExpressionFunction(name, handler) {
@@ -3821,8 +4000,10 @@ var BeaconPlugin = function() {
3821
4000
  var matches = exp.match(/^@\[(.*)\]@$/);
3822
4001
  var matchedExp = exp;
3823
4002
  if (matches) {
3824
- var ref;
3825
- ref = _sliced_to_array(Array.from(matches), 2), matchedExp = ref[1], ref;
4003
+ var _Array_from = _sliced_to_array(Array.from(matches), 2), matched = _Array_from[1];
4004
+ if (matched) {
4005
+ matchedExp = matched;
4006
+ }
3826
4007
  }
3827
4008
  var storedAST;
3828
4009
  try {
@@ -3851,6 +4032,8 @@ var BeaconPlugin = function() {
3851
4032
  value: function _resolveNode(_currentValue, node, options) {
3852
4033
  var _this = this;
3853
4034
  var resolveNode = options.resolveNode, model = options.model;
4035
+ var _options_async;
4036
+ var isAsync = (_options_async = options.async) !== null && _options_async !== void 0 ? _options_async : false;
3854
4037
  var expressionContext = _object_spread_props(_object_spread({}, options), {
3855
4038
  evaluate: function(expr) {
3856
4039
  return _this.evaluate(expr, options);
@@ -3870,11 +4053,33 @@ var BeaconPlugin = function() {
3870
4053
  if (operator) {
3871
4054
  if ("resolveParams" in operator) {
3872
4055
  if (operator.resolveParams === false) {
3873
- return operator(expressionContext, node.left, node.right);
4056
+ return operator(expressionContext, node.left, node.right, isAsync);
4057
+ }
4058
+ var left2 = resolveNode(node.left);
4059
+ var right2 = resolveNode(node.right);
4060
+ if (options.async && (isAwaitable(left2) || isAwaitable(right2))) {
4061
+ return collateAwaitable([
4062
+ left2,
4063
+ right2
4064
+ ]).awaitableThen(function(param) {
4065
+ var _param = _sliced_to_array(param, 2), leftVal = _param[0], rightVal = _param[1];
4066
+ return operator(expressionContext, leftVal, rightVal, isAsync);
4067
+ });
3874
4068
  }
3875
- return operator(expressionContext, resolveNode(node.left), resolveNode(node.right));
4069
+ return operator(expressionContext, left2, right2, isAsync);
4070
+ }
4071
+ var left = resolveNode(node.left);
4072
+ var right = resolveNode(node.right);
4073
+ if (options.async && (isAwaitable(left) || isAwaitable(right))) {
4074
+ return collateAwaitable([
4075
+ left,
4076
+ right
4077
+ ]).awaitableThen(function(param) {
4078
+ var _param = _sliced_to_array(param, 2), leftVal = _param[0], rightVal = _param[1];
4079
+ return operator(leftVal, rightVal, isAsync);
4080
+ });
3876
4081
  }
3877
- return operator(resolveNode(node.left), resolveNode(node.right));
4082
+ return operator(left, right, isAsync);
3878
4083
  }
3879
4084
  return;
3880
4085
  }
@@ -3882,21 +4087,29 @@ var BeaconPlugin = function() {
3882
4087
  var operator1 = this.operators.unary.get(node.operator);
3883
4088
  if (operator1) {
3884
4089
  if ("resolveParams" in operator1) {
3885
- return operator1(expressionContext, operator1.resolveParams === false ? node.argument : resolveNode(node.argument));
4090
+ if (operator1.resolveParams === false) {
4091
+ return operator1(expressionContext, node.argument, isAsync);
4092
+ }
4093
+ var arg2 = resolveNode(node.argument);
4094
+ if (options.async && isAwaitable(arg2)) {
4095
+ return arg2.awaitableThen(function(argVal) {
4096
+ return operator1(expressionContext, argVal, isAsync);
4097
+ });
4098
+ }
4099
+ return operator1(expressionContext, arg2, isAsync);
3886
4100
  }
3887
- return operator1(resolveNode(node.argument));
4101
+ var arg = resolveNode(node.argument);
4102
+ if (options.async && isAwaitable(arg)) {
4103
+ return arg.awaitableThen(function(argVal) {
4104
+ return operator1(argVal, isAsync);
4105
+ });
4106
+ }
4107
+ return operator1(arg, isAsync);
3888
4108
  }
3889
4109
  return;
3890
4110
  }
3891
4111
  if (node.type === "Object") {
3892
- var attributes = node.attributes;
3893
- var resolvedAttributes = {};
3894
- attributes.forEach(function(attr) {
3895
- var key = resolveNode(attr.key);
3896
- var value = resolveNode(attr.value);
3897
- resolvedAttributes[key] = value;
3898
- });
3899
- return resolvedAttributes;
4112
+ return PromiseCollectionHandler.handleObject(node.attributes, resolveNode, options.async || false);
3900
4113
  }
3901
4114
  if (node.type === "CallExpression") {
3902
4115
  var expressionName = node.callTarget.name;
@@ -3904,6 +4117,9 @@ var BeaconPlugin = function() {
3904
4117
  if (!operator2) {
3905
4118
  throw new Error("Unknown expression function: ".concat(expressionName));
3906
4119
  }
4120
+ if (operator2.name === waitFor.name && !options.async) {
4121
+ throw new Error("Usage of await outside of async context");
4122
+ }
3907
4123
  if ("resolveParams" in operator2 && operator2.resolveParams === false) {
3908
4124
  return operator2.apply(void 0, [
3909
4125
  expressionContext
@@ -3912,6 +4128,16 @@ var BeaconPlugin = function() {
3912
4128
  var args = node.args.map(function(n) {
3913
4129
  return resolveNode(n);
3914
4130
  });
4131
+ if (options.async) {
4132
+ var hasPromises = args.some(isAwaitable);
4133
+ if (hasPromises) {
4134
+ return collateAwaitable(args).awaitableThen(function(resolvedArgs) {
4135
+ return operator2.apply(void 0, [
4136
+ expressionContext
4137
+ ].concat(_to_consumable_array(resolvedArgs)));
4138
+ });
4139
+ }
4140
+ }
3915
4141
  return operator2.apply(void 0, [
3916
4142
  expressionContext
3917
4143
  ].concat(_to_consumable_array(args)));
@@ -3926,11 +4152,36 @@ var BeaconPlugin = function() {
3926
4152
  if (node.type === "MemberExpression") {
3927
4153
  var obj = resolveNode(node.object);
3928
4154
  var prop = resolveNode(node.property);
4155
+ if (options.async && (isAwaitable(obj) || isAwaitable(prop))) {
4156
+ return collateAwaitable([
4157
+ obj,
4158
+ prop
4159
+ ]).awaitableThen(function(param) {
4160
+ var _param = _sliced_to_array(param, 2), objVal = _param[0], propVal = _param[1];
4161
+ return objVal[propVal];
4162
+ });
4163
+ }
3929
4164
  return obj[prop];
3930
4165
  }
3931
4166
  if (node.type === "Assignment") {
3932
4167
  if (node.left.type === "ModelRef") {
3933
4168
  var value = resolveNode(node.right);
4169
+ if (isPromiseLike(value)) {
4170
+ if (options.async && isAwaitable(value)) {
4171
+ return value.awaitableThen(function(resolvedValue) {
4172
+ model.set([
4173
+ [
4174
+ node.left.ref,
4175
+ resolvedValue
4176
+ ]
4177
+ ]);
4178
+ return resolvedValue;
4179
+ });
4180
+ } else {
4181
+ var _options_logger;
4182
+ (_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");
4183
+ }
4184
+ }
3934
4185
  model.set([
3935
4186
  [
3936
4187
  node.left.ref,
@@ -3941,19 +4192,30 @@ var BeaconPlugin = function() {
3941
4192
  }
3942
4193
  if (node.left.type === "Identifier") {
3943
4194
  var value1 = resolveNode(node.right);
4195
+ if (options.async && isAwaitable(value1)) {
4196
+ return value1.awaitableThen(function(resolvedValue) {
4197
+ _this.vars[node.left.name] = resolvedValue;
4198
+ return resolvedValue;
4199
+ });
4200
+ }
3944
4201
  this.vars[node.left.name] = value1;
3945
4202
  return value1;
3946
4203
  }
3947
4204
  return;
3948
4205
  }
3949
4206
  if (node.type === "ConditionalExpression") {
3950
- var result = resolveNode(node.test) ? node.consequent : node.alternate;
3951
- return resolveNode(result);
4207
+ var testResult = resolveNode(node.test);
4208
+ return handleConditionalBranching(testResult, function() {
4209
+ return node.consequent;
4210
+ }, function() {
4211
+ return node.alternate;
4212
+ }, resolveNode, isAsync);
3952
4213
  }
3953
4214
  if (node.type === "ArrayExpression") {
3954
- return node.elements.map(function(ele) {
4215
+ var results = node.elements.map(function(ele) {
3955
4216
  return resolveNode(ele);
3956
4217
  });
4218
+ return PromiseCollectionHandler.handleArray(results, isAsync);
3957
4219
  }
3958
4220
  if (node.type === "Modification") {
3959
4221
  var operation = this.operators.binary.get(node.operator);
@@ -3961,14 +4223,49 @@ var BeaconPlugin = function() {
3961
4223
  var newValue;
3962
4224
  if ("resolveParams" in operation) {
3963
4225
  if (operation.resolveParams === false) {
3964
- newValue = operation(expressionContext, node.left, node.right);
4226
+ newValue = operation(expressionContext, node.left, node.right, isAsync);
3965
4227
  } else {
3966
- newValue = operation(expressionContext, resolveNode(node.left), resolveNode(node.right));
4228
+ var left1 = resolveNode(node.left);
4229
+ var right1 = resolveNode(node.right);
4230
+ if (options.async && (isAwaitable(left1) || isAwaitable(right1))) {
4231
+ newValue = collateAwaitable([
4232
+ left1,
4233
+ right1
4234
+ ]).awaitableThen(function(param) {
4235
+ var _param = _sliced_to_array(param, 2), leftVal = _param[0], rightVal = _param[1];
4236
+ return operation(expressionContext, leftVal, rightVal, isAsync);
4237
+ });
4238
+ } else {
4239
+ newValue = operation(expressionContext, left1, right1, isAsync);
4240
+ }
3967
4241
  }
3968
4242
  } else {
3969
- newValue = operation(resolveNode(node.left), resolveNode(node.right));
4243
+ var left3 = resolveNode(node.left);
4244
+ var right3 = resolveNode(node.right);
4245
+ if (options.async && (isAwaitable(left3) || isAwaitable(right3))) {
4246
+ newValue = collateAwaitable([
4247
+ left3,
4248
+ right3
4249
+ ]).awaitableThen(function(param) {
4250
+ var _param = _sliced_to_array(param, 2), leftVal = _param[0], rightVal = _param[1];
4251
+ return operation(leftVal, rightVal, isAsync);
4252
+ });
4253
+ } else {
4254
+ newValue = operation(left3, right3, isAsync);
4255
+ }
3970
4256
  }
3971
4257
  if (node.left.type === "ModelRef") {
4258
+ if (options.async && isAwaitable(newValue)) {
4259
+ return newValue.awaitableThen(function(resolvedValue) {
4260
+ model.set([
4261
+ [
4262
+ node.left.ref,
4263
+ resolvedValue
4264
+ ]
4265
+ ]);
4266
+ return resolvedValue;
4267
+ });
4268
+ }
3972
4269
  model.set([
3973
4270
  [
3974
4271
  node.left.ref,
@@ -3976,6 +4273,12 @@ var BeaconPlugin = function() {
3976
4273
  ]
3977
4274
  ]);
3978
4275
  } else if (node.left.type === "Identifier") {
4276
+ if (options.async && isAwaitable(newValue)) {
4277
+ return newValue.awaitableThen(function(resolvedValue) {
4278
+ _this.vars[node.left.name] = resolvedValue;
4279
+ return resolvedValue;
4280
+ });
4281
+ }
3979
4282
  this.vars[node.left.name] = newValue;
3980
4283
  }
3981
4284
  return newValue;
@@ -4841,20 +5144,15 @@ var BeaconPlugin = function() {
4841
5144
  }();
4842
5145
  var ViewInstance = /*#__PURE__*/ function() {
4843
5146
  function ViewInstance(initialView, resolverOptions) {
4844
- var _this = this;
4845
5147
  _class_call_check(this, ViewInstance);
4846
5148
  this.hooks = {
4847
5149
  onUpdate: new SyncHook(),
4848
5150
  parser: new SyncHook(),
4849
5151
  resolver: new SyncHook(),
4850
- onTemplatePluginCreated: new SyncHook(),
4851
5152
  templatePlugin: new SyncHook()
4852
5153
  };
4853
5154
  this.initialView = initialView;
4854
5155
  this.resolverOptions = resolverOptions;
4855
- this.hooks.onTemplatePluginCreated.tap("view", function(templatePlugin) {
4856
- _this.templatePlugin = templatePlugin;
4857
- });
4858
5156
  }
4859
5157
  _create_class(ViewInstance, [
4860
5158
  {
@@ -4901,6 +5199,12 @@ var BeaconPlugin = function() {
4901
5199
  var _this_validationProvider;
4902
5200
  return (_this_validationProvider = this.validationProvider) === null || _this_validationProvider === void 0 ? void 0 : _this_validationProvider.getValidationsForBinding(binding);
4903
5201
  }
5202
+ },
5203
+ {
5204
+ key: "setTemplatePlugin",
5205
+ value: function setTemplatePlugin(plugin) {
5206
+ this.templatePlugin = plugin;
5207
+ }
4904
5208
  }
4905
5209
  ]);
4906
5210
  return ViewInstance;
@@ -5072,6 +5376,7 @@ var BeaconPlugin = function() {
5072
5376
  value: function apply(view) {
5073
5377
  view.hooks.parser.tap("template", this.applyParser.bind(this));
5074
5378
  view.hooks.resolver.tap("template", this.applyResolverHooks.bind(this));
5379
+ view.setTemplatePlugin(this);
5075
5380
  }
5076
5381
  }
5077
5382
  ]);
@@ -6680,8 +6985,7 @@ var BeaconPlugin = function() {
6680
6985
  var _this1 = this;
6681
6986
  _class_call_check(this, ViewController);
6682
6987
  this.hooks = {
6683
- /** Do any processing before the `View` instance is created */ resolveView: new SyncWaterfallHook(),
6684
- // The hook right before the View starts resolving. Attach anything custom here
6988
+ resolveView: new SyncWaterfallHook(),
6685
6989
  view: new SyncHook()
6686
6990
  };
6687
6991
  this.transformRegistry = new Registry();
@@ -6729,6 +7033,7 @@ var BeaconPlugin = function() {
6729
7033
  ]));
6730
7034
  }
6731
7035
  });
7036
+ this.viewPlugins = this.createViewPlugins();
6732
7037
  }
6733
7038
  _create_class(ViewController, [
6734
7039
  {
@@ -6784,9 +7089,50 @@ var BeaconPlugin = function() {
6784
7089
  }
6785
7090
  var view = new ViewInstance(source, this.viewOptions);
6786
7091
  this.currentView = view;
7092
+ this.applyViewPlugins(view);
6787
7093
  this.hooks.view.call(view);
6788
7094
  view.update();
6789
7095
  }
7096
+ },
7097
+ {
7098
+ key: "applyViewPlugins",
7099
+ value: function applyViewPlugins(view) {
7100
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
7101
+ try {
7102
+ for(var _iterator = this.viewPlugins[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
7103
+ var plugin = _step.value;
7104
+ plugin.apply(view);
7105
+ }
7106
+ } catch (err) {
7107
+ _didIteratorError = true;
7108
+ _iteratorError = err;
7109
+ } finally{
7110
+ try {
7111
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
7112
+ _iterator.return();
7113
+ }
7114
+ } finally{
7115
+ if (_didIteratorError) {
7116
+ throw _iteratorError;
7117
+ }
7118
+ }
7119
+ }
7120
+ }
7121
+ },
7122
+ {
7123
+ key: "createViewPlugins",
7124
+ value: function createViewPlugins() {
7125
+ var pluginOptions = toNodeResolveOptions(this.viewOptions);
7126
+ return [
7127
+ new AssetPlugin(),
7128
+ new SwitchPlugin(pluginOptions),
7129
+ new ApplicabilityPlugin(),
7130
+ new AssetTransformCorePlugin(this.transformRegistry),
7131
+ new StringResolverPlugin(),
7132
+ new TemplatePlugin(pluginOptions),
7133
+ new MultiNodePlugin()
7134
+ ];
7135
+ }
6790
7136
  }
6791
7137
  ]);
6792
7138
  return ViewController;
@@ -7159,35 +7505,6 @@ var BeaconPlugin = function() {
7159
7505
  ref: Symbol("not-started"),
7160
7506
  status: "not-started"
7161
7507
  };
7162
- var DefaultViewPlugin = /*#__PURE__*/ function() {
7163
- function DefaultViewPlugin() {
7164
- _class_call_check(this, DefaultViewPlugin);
7165
- this.name = "default-view-plugin";
7166
- }
7167
- _create_class(DefaultViewPlugin, [
7168
- {
7169
- key: "apply",
7170
- value: function apply(player) {
7171
- var _this = this;
7172
- player.hooks.viewController.tap(this.name, function(viewController) {
7173
- viewController.hooks.view.tap(_this.name, function(view) {
7174
- var pluginOptions = toNodeResolveOptions(view.resolverOptions);
7175
- new AssetPlugin().apply(view);
7176
- new SwitchPlugin(pluginOptions).apply(view);
7177
- new ApplicabilityPlugin().apply(view);
7178
- new AssetTransformCorePlugin(viewController.transformRegistry).apply(view);
7179
- new StringResolverPlugin().apply(view);
7180
- var templatePlugin = new TemplatePlugin(pluginOptions);
7181
- templatePlugin.apply(view);
7182
- view.hooks.onTemplatePluginCreated.call(templatePlugin);
7183
- new MultiNodePlugin().apply(view);
7184
- });
7185
- });
7186
- }
7187
- }
7188
- ]);
7189
- return DefaultViewPlugin;
7190
- }();
7191
7508
  var PLAYER_VERSION = "__VERSION__";
7192
7509
  var COMMIT = "__GIT_COMMIT__";
7193
7510
  var _Player = /*#__PURE__*/ function() {
@@ -7199,26 +7516,25 @@ var BeaconPlugin = function() {
7199
7516
  this.constantsController = new ConstantsController();
7200
7517
  this.state = NOT_STARTED_STATE;
7201
7518
  this.hooks = {
7202
- /** The hook that fires every time we create a new flowController (a new Content blob is passed in) */ flowController: new SyncHook(),
7203
- /** The hook that updates/handles views */ viewController: new SyncHook(),
7204
- /** A hook called every-time there's a new view. This is equivalent to the view hook on the view-controller */ view: new SyncHook(),
7205
- /** Called when an expression evaluator was created */ expressionEvaluator: new SyncHook(),
7206
- /** The hook that creates and manages data */ dataController: new SyncHook(),
7207
- /** Called after the schema is created for a flow */ schema: new SyncHook(),
7208
- /** Manages validations (schema and x-field ) */ validationController: new SyncHook(),
7209
- /** Manages parsing binding */ bindingParser: new SyncHook(),
7210
- /** A that's called for state changes in the flow execution */ state: new SyncHook(),
7211
- /** A hook to access the current flow */ onStart: new SyncHook(),
7212
- /** A hook for when the flow ends either in success or failure */ onEnd: new SyncHook(),
7213
- /** Mutate the Content flow before starting */ resolveFlowContent: new SyncWaterfallHook()
7519
+ flowController: new SyncHook(),
7520
+ viewController: new SyncHook(),
7521
+ view: new SyncHook(),
7522
+ expressionEvaluator: new SyncHook(),
7523
+ dataController: new SyncHook(),
7524
+ schema: new SyncHook(),
7525
+ validationController: new SyncHook(),
7526
+ bindingParser: new SyncHook(),
7527
+ state: new SyncHook(),
7528
+ onStart: new SyncHook(),
7529
+ onEnd: new SyncHook(),
7530
+ resolveFlowContent: new SyncWaterfallHook()
7214
7531
  };
7215
7532
  if (config === null || config === void 0 ? void 0 : config.logger) {
7216
7533
  this.logger.addHandler(config.logger);
7217
7534
  }
7218
7535
  this.config = config || {};
7219
7536
  this.config.plugins = [
7220
- new DefaultExpPlugin(),
7221
- new DefaultViewPlugin()
7537
+ new DefaultExpPlugin()
7222
7538
  ].concat(_to_consumable_array(this.config.plugins || []), [
7223
7539
  new FlowExpPlugin()
7224
7540
  ]);
@@ -7410,10 +7726,90 @@ var BeaconPlugin = function() {
7410
7726
  var value = (_flowInstance_currentState = flowInstance.currentState) === null || _flowInstance_currentState === void 0 ? void 0 : _flowInstance_currentState.value;
7411
7727
  if (value && value.state_type === "ACTION") {
7412
7728
  var exp = value.exp;
7413
- flowController === null || flowController === void 0 ? void 0 : flowController.transition(String(expressionEvaluator === null || expressionEvaluator === void 0 ? void 0 : expressionEvaluator.evaluate(exp)));
7729
+ var result = expressionEvaluator.evaluate(exp);
7730
+ if (isPromiseLike(result)) {
7731
+ _this.logger.warn("Async expression used as return value in in non-async context, transitioning with '*' value");
7732
+ }
7733
+ flowController === null || flowController === void 0 ? void 0 : flowController.transition(String(result));
7414
7734
  }
7415
7735
  expressionEvaluator.reset();
7416
7736
  });
7737
+ var _this1 = _this;
7738
+ flow.hooks.afterTransition.tap("player", function() {
7739
+ var _ref = _async_to_generator(function(flowInstance) {
7740
+ var _flowInstance_currentState, value, exp, result, e;
7741
+ return _ts_generator(this, function(_state) {
7742
+ switch(_state.label){
7743
+ case 0:
7744
+ value = (_flowInstance_currentState = flowInstance.currentState) === null || _flowInstance_currentState === void 0 ? void 0 : _flowInstance_currentState.value;
7745
+ if (!(value && value.state_type === "ASYNC_ACTION")) return [
7746
+ 3,
7747
+ 8
7748
+ ];
7749
+ exp = value.exp;
7750
+ _state.label = 1;
7751
+ case 1:
7752
+ _state.trys.push([
7753
+ 1,
7754
+ 7,
7755
+ ,
7756
+ 8
7757
+ ]);
7758
+ result = expressionEvaluator.evaluateAsync(exp);
7759
+ if (!isPromiseLike(result)) return [
7760
+ 3,
7761
+ 5
7762
+ ];
7763
+ if (!value.await) return [
7764
+ 3,
7765
+ 3
7766
+ ];
7767
+ return [
7768
+ 4,
7769
+ result
7770
+ ];
7771
+ case 2:
7772
+ result = _state.sent();
7773
+ return [
7774
+ 3,
7775
+ 4
7776
+ ];
7777
+ case 3:
7778
+ _this1.logger.warn("Unawaited promise used as return value in in non-async context, transitioning with '*' value");
7779
+ _state.label = 4;
7780
+ case 4:
7781
+ return [
7782
+ 3,
7783
+ 6
7784
+ ];
7785
+ case 5:
7786
+ _this1.logger.warn("Non async expression used in async action node");
7787
+ _state.label = 6;
7788
+ case 6:
7789
+ flowController === null || flowController === void 0 ? void 0 : flowController.transition(String(result));
7790
+ return [
7791
+ 3,
7792
+ 8
7793
+ ];
7794
+ case 7:
7795
+ e = _state.sent();
7796
+ flowResultDeferred.reject(e);
7797
+ return [
7798
+ 3,
7799
+ 8
7800
+ ];
7801
+ case 8:
7802
+ expressionEvaluator.reset();
7803
+ return [
7804
+ 2
7805
+ ];
7806
+ }
7807
+ });
7808
+ });
7809
+ return function(flowInstance) {
7810
+ return _ref.apply(this, arguments);
7811
+ };
7812
+ }());
7417
7813
  });
7418
7814
  this.hooks.dataController.call(dataController);
7419
7815
  validationController.setOptions({
@@ -7451,11 +7847,9 @@ var BeaconPlugin = function() {
7451
7847
  }),
7452
7848
  constants: this.constantsController
7453
7849
  });
7454
- this.hooks.viewController.tap("player", function(vc) {
7455
- vc.hooks.view.tap("player", function(view) {
7456
- validationController.onView(view);
7457
- _this.hooks.view.call(view);
7458
- });
7850
+ viewController.hooks.view.tap("player", function(view) {
7851
+ validationController.onView(view);
7852
+ _this.hooks.view.call(view);
7459
7853
  });
7460
7854
  this.hooks.viewController.call(viewController);
7461
7855
  return {