@player-ui/stage-revert-data-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 StageRevertDataPlugin = 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();
@@ -3512,8 +3561,19 @@ var StageRevertDataPlugin = function() {
3512
3561
  },
3513
3562
  setDataVal: function() {
3514
3563
  return setDataVal;
3564
+ },
3565
+ waitFor: function() {
3566
+ return waitFor;
3515
3567
  }
3516
3568
  });
3569
+ var AwaitableSymbol = Symbol("Awaitable");
3570
+ function makeAwaitable(promise) {
3571
+ promise[AwaitableSymbol] = AwaitableSymbol;
3572
+ promise.awaitableThen = function(arg) {
3573
+ return makeAwaitable(promise.then(arg));
3574
+ };
3575
+ return promise;
3576
+ }
3517
3577
  var setDataVal = function(_context, binding, value) {
3518
3578
  _context.model.set([
3519
3579
  [
@@ -3529,8 +3589,19 @@ var StageRevertDataPlugin = function() {
3529
3589
  return _context.model.delete(binding);
3530
3590
  };
3531
3591
  var conditional = function(ctx, condition, ifTrue, ifFalse) {
3532
- var resolution = ctx.evaluate(condition);
3533
- if (resolution) {
3592
+ var testResult = ctx.evaluate(condition);
3593
+ if (isAwaitable(testResult)) {
3594
+ return testResult.awaitableThen(function(resolvedTest) {
3595
+ if (resolvedTest) {
3596
+ return ctx.evaluate(ifTrue);
3597
+ }
3598
+ if (ifFalse) {
3599
+ return ctx.evaluate(ifFalse);
3600
+ }
3601
+ return null;
3602
+ });
3603
+ }
3604
+ if (testResult) {
3534
3605
  return ctx.evaluate(ifTrue);
3535
3606
  }
3536
3607
  if (ifFalse) {
@@ -3539,12 +3610,15 @@ var StageRevertDataPlugin = function() {
3539
3610
  return null;
3540
3611
  };
3541
3612
  conditional.resolveParams = false;
3542
- var andandOperator = function(ctx, a, b) {
3543
- return ctx.evaluate(a) && ctx.evaluate(b);
3613
+ var waitFor = function(ctx, promise) {
3614
+ return makeAwaitable(promise);
3615
+ };
3616
+ var andandOperator = function(ctx, a, b, async) {
3617
+ return LogicalOperators.and(ctx, a, b, async);
3544
3618
  };
3545
3619
  andandOperator.resolveParams = false;
3546
- var ororOperator = function(ctx, a, b) {
3547
- return ctx.evaluate(a) || ctx.evaluate(b);
3620
+ var ororOperator = function(ctx, a, b, async) {
3621
+ return LogicalOperators.or(ctx, a, b, async);
3548
3622
  };
3549
3623
  ororOperator.resolveParams = false;
3550
3624
  var DEFAULT_BINARY_OPERATORS = {
@@ -3564,34 +3638,35 @@ var StageRevertDataPlugin = function() {
3564
3638
  "%": function(a, b) {
3565
3639
  return a % b;
3566
3640
  },
3641
+ // Promise-aware comparison operators
3567
3642
  // eslint-disable-next-line
3568
- "==": function(a, b) {
3643
+ "==": makePromiseAwareBinaryOp(function(a, b) {
3569
3644
  return a == b;
3570
- },
3645
+ }),
3571
3646
  // eslint-disable-next-line
3572
- "!=": function(a, b) {
3647
+ "!=": makePromiseAwareBinaryOp(function(a, b) {
3573
3648
  return a != b;
3574
- },
3575
- ">": function(a, b) {
3649
+ }),
3650
+ ">": makePromiseAwareBinaryOp(function(a, b) {
3576
3651
  return a > b;
3577
- },
3578
- ">=": function(a, b) {
3652
+ }),
3653
+ ">=": makePromiseAwareBinaryOp(function(a, b) {
3579
3654
  return a >= b;
3580
- },
3581
- "<": function(a, b) {
3655
+ }),
3656
+ "<": makePromiseAwareBinaryOp(function(a, b) {
3582
3657
  return a < b;
3583
- },
3584
- "<=": function(a, b) {
3658
+ }),
3659
+ "<=": makePromiseAwareBinaryOp(function(a, b) {
3585
3660
  return a <= b;
3586
- },
3587
- "&&": andandOperator,
3588
- "||": ororOperator,
3589
- "!==": function(a, b) {
3661
+ }),
3662
+ "!==": makePromiseAwareBinaryOp(function(a, b) {
3590
3663
  return a !== b;
3591
- },
3592
- "===": function(a, b) {
3664
+ }),
3665
+ "===": makePromiseAwareBinaryOp(function(a, b) {
3593
3666
  return a === b;
3594
- },
3667
+ }),
3668
+ "&&": andandOperator,
3669
+ "||": ororOperator,
3595
3670
  // eslint-disable-next-line
3596
3671
  "|": function(a, b) {
3597
3672
  return a | b;
@@ -3622,8 +3697,73 @@ var StageRevertDataPlugin = function() {
3622
3697
  "+": function(a) {
3623
3698
  return Number(a);
3624
3699
  },
3625
- "!": function(a) {
3700
+ "!": makePromiseAwareUnaryOp(function(a) {
3626
3701
  return !a;
3702
+ })
3703
+ };
3704
+ var PromiseCollectionHandler = {
3705
+ /**
3706
+ * Handle array with potential Promise elements
3707
+ */ handleArray: function handleArray(items, async) {
3708
+ if (!async) {
3709
+ return items;
3710
+ }
3711
+ var hasPromises = items.some(function(item) {
3712
+ return isAwaitable(item);
3713
+ });
3714
+ return hasPromises ? collateAwaitable(items) : items;
3715
+ },
3716
+ /**
3717
+ * Handle object with potential Promise keys/values
3718
+ */ handleObject: function handleObject(attributes, resolveNode, async) {
3719
+ var resolvedAttributes = {};
3720
+ var promises = [];
3721
+ var hasPromises = false;
3722
+ attributes.forEach(function(attr) {
3723
+ var key = resolveNode(attr.key);
3724
+ var value = resolveNode(attr.value);
3725
+ if (async && (isAwaitable(key) || isAwaitable(value))) {
3726
+ hasPromises = true;
3727
+ var keyPromise = Promise.resolve(key);
3728
+ var valuePromise = Promise.resolve(value);
3729
+ promises.push(collateAwaitable([
3730
+ keyPromise,
3731
+ valuePromise
3732
+ ]).awaitableThen(function(param) {
3733
+ var _param = _sliced_to_array(param, 2), resolvedKey = _param[0], resolvedValue = _param[1];
3734
+ resolvedAttributes[resolvedKey] = resolvedValue;
3735
+ }));
3736
+ } else {
3737
+ resolvedAttributes[key] = value;
3738
+ }
3739
+ });
3740
+ return hasPromises ? collateAwaitable(promises).awaitableThen(function() {
3741
+ return resolvedAttributes;
3742
+ }) : resolvedAttributes;
3743
+ }
3744
+ };
3745
+ var LogicalOperators = {
3746
+ and: function(ctx, leftNode, rightNode, async) {
3747
+ var leftResult = ctx.evaluate(leftNode);
3748
+ if (async && isAwaitable(leftResult)) {
3749
+ return leftResult.awaitableThen(function(awaitedLeft) {
3750
+ if (!awaitedLeft) return awaitedLeft;
3751
+ var rightResult = ctx.evaluate(rightNode);
3752
+ return isAwaitable(rightResult) ? rightResult : Promise.resolve(rightResult);
3753
+ });
3754
+ }
3755
+ return leftResult && ctx.evaluate(rightNode);
3756
+ },
3757
+ or: function(ctx, leftNode, rightNode, async) {
3758
+ var leftResult = ctx.evaluate(leftNode);
3759
+ if (async && isAwaitable(leftResult)) {
3760
+ return leftResult.awaitableThen(function(awaitedLeft) {
3761
+ if (awaitedLeft) return awaitedLeft;
3762
+ var rightResult = ctx.evaluate(rightNode);
3763
+ return isAwaitable(rightResult) ? rightResult : Promise.resolve(rightResult);
3764
+ });
3765
+ }
3766
+ return leftResult || ctx.evaluate(rightNode);
3627
3767
  }
3628
3768
  };
3629
3769
  var ExpressionEvaluator = /*#__PURE__*/ function() {
@@ -3644,7 +3784,12 @@ var StageRevertDataPlugin = function() {
3644
3784
  this.operators = {
3645
3785
  binary: new Map(Object.entries(DEFAULT_BINARY_OPERATORS)),
3646
3786
  unary: new Map(Object.entries(DEFAULT_UNARY_OPERATORS)),
3647
- expressions: new Map(Object.entries(evaluator_functions_exports))
3787
+ expressions: new Map(_to_consumable_array(Object.entries(evaluator_functions_exports)).concat([
3788
+ [
3789
+ "await",
3790
+ waitFor
3791
+ ]
3792
+ ]))
3648
3793
  };
3649
3794
  this.defaultHookOptions = _object_spread_props(_object_spread({}, defaultOptions), {
3650
3795
  evaluate: function(expr) {
@@ -3654,7 +3799,9 @@ var StageRevertDataPlugin = function() {
3654
3799
  return _this._execAST(node, _this.defaultHookOptions);
3655
3800
  }
3656
3801
  });
3657
- this.hooks.resolve.tap("ExpressionEvaluator", this._resolveNode.bind(this));
3802
+ this.hooks.resolve.tap("ExpressionEvaluator", function(result, node, options) {
3803
+ return _this._resolveNode(result, node, options);
3804
+ });
3658
3805
  this.evaluate = this.evaluate.bind(this);
3659
3806
  }
3660
3807
  _create_class(ExpressionEvaluator, [
@@ -3692,6 +3839,38 @@ var StageRevertDataPlugin = function() {
3692
3839
  return this._execString(String(expression), resolvedOpts);
3693
3840
  }
3694
3841
  },
3842
+ {
3843
+ /**
3844
+ * Evaluate functions in an async context
3845
+ * @experimental These Player APIs are in active development and may change. Use with caution
3846
+ */ key: "evaluateAsync",
3847
+ value: function evaluateAsync(expr, options) {
3848
+ if (Array.isArray(expr)) {
3849
+ var _this = this;
3850
+ return collateAwaitable(expr.map(function() {
3851
+ var _ref = _async_to_generator(function(exp) {
3852
+ return _ts_generator(this, function(_state) {
3853
+ return [
3854
+ 2,
3855
+ _this.evaluate(exp, _object_spread_props(_object_spread({}, options), {
3856
+ async: true
3857
+ }))
3858
+ ];
3859
+ });
3860
+ });
3861
+ return function(exp) {
3862
+ return _ref.apply(this, arguments);
3863
+ };
3864
+ }())).awaitableThen(function(values) {
3865
+ return values.pop();
3866
+ });
3867
+ } else {
3868
+ return this.evaluate(expr, _object_spread_props(_object_spread({}, options), {
3869
+ async: true
3870
+ }));
3871
+ }
3872
+ }
3873
+ },
3695
3874
  {
3696
3875
  key: "addExpressionFunction",
3697
3876
  value: function addExpressionFunction(name, handler) {
@@ -3737,8 +3916,10 @@ var StageRevertDataPlugin = function() {
3737
3916
  var matches = exp.match(/^@\[(.*)\]@$/);
3738
3917
  var matchedExp = exp;
3739
3918
  if (matches) {
3740
- var ref;
3741
- ref = _sliced_to_array(Array.from(matches), 2), matchedExp = ref[1], ref;
3919
+ var _Array_from = _sliced_to_array(Array.from(matches), 2), matched = _Array_from[1];
3920
+ if (matched) {
3921
+ matchedExp = matched;
3922
+ }
3742
3923
  }
3743
3924
  var storedAST;
3744
3925
  try {
@@ -3767,6 +3948,8 @@ var StageRevertDataPlugin = function() {
3767
3948
  value: function _resolveNode(_currentValue, node, options) {
3768
3949
  var _this = this;
3769
3950
  var resolveNode = options.resolveNode, model = options.model;
3951
+ var _options_async;
3952
+ var isAsync = (_options_async = options.async) !== null && _options_async !== void 0 ? _options_async : false;
3770
3953
  var expressionContext = _object_spread_props(_object_spread({}, options), {
3771
3954
  evaluate: function(expr) {
3772
3955
  return _this.evaluate(expr, options);
@@ -3786,11 +3969,33 @@ var StageRevertDataPlugin = function() {
3786
3969
  if (operator) {
3787
3970
  if ("resolveParams" in operator) {
3788
3971
  if (operator.resolveParams === false) {
3789
- return operator(expressionContext, node.left, node.right);
3972
+ return operator(expressionContext, node.left, node.right, isAsync);
3973
+ }
3974
+ var left2 = resolveNode(node.left);
3975
+ var right2 = resolveNode(node.right);
3976
+ if (options.async && (isAwaitable(left2) || isAwaitable(right2))) {
3977
+ return collateAwaitable([
3978
+ left2,
3979
+ right2
3980
+ ]).awaitableThen(function(param) {
3981
+ var _param = _sliced_to_array(param, 2), leftVal = _param[0], rightVal = _param[1];
3982
+ return operator(expressionContext, leftVal, rightVal, isAsync);
3983
+ });
3790
3984
  }
3791
- return operator(expressionContext, resolveNode(node.left), resolveNode(node.right));
3985
+ return operator(expressionContext, left2, right2, isAsync);
3986
+ }
3987
+ var left = resolveNode(node.left);
3988
+ var right = resolveNode(node.right);
3989
+ if (options.async && (isAwaitable(left) || isAwaitable(right))) {
3990
+ return collateAwaitable([
3991
+ left,
3992
+ right
3993
+ ]).awaitableThen(function(param) {
3994
+ var _param = _sliced_to_array(param, 2), leftVal = _param[0], rightVal = _param[1];
3995
+ return operator(leftVal, rightVal, isAsync);
3996
+ });
3792
3997
  }
3793
- return operator(resolveNode(node.left), resolveNode(node.right));
3998
+ return operator(left, right, isAsync);
3794
3999
  }
3795
4000
  return;
3796
4001
  }
@@ -3798,21 +4003,29 @@ var StageRevertDataPlugin = function() {
3798
4003
  var operator1 = this.operators.unary.get(node.operator);
3799
4004
  if (operator1) {
3800
4005
  if ("resolveParams" in operator1) {
3801
- return operator1(expressionContext, operator1.resolveParams === false ? node.argument : resolveNode(node.argument));
4006
+ if (operator1.resolveParams === false) {
4007
+ return operator1(expressionContext, node.argument, isAsync);
4008
+ }
4009
+ var arg2 = resolveNode(node.argument);
4010
+ if (options.async && isAwaitable(arg2)) {
4011
+ return arg2.awaitableThen(function(argVal) {
4012
+ return operator1(expressionContext, argVal, isAsync);
4013
+ });
4014
+ }
4015
+ return operator1(expressionContext, arg2, isAsync);
3802
4016
  }
3803
- return operator1(resolveNode(node.argument));
4017
+ var arg = resolveNode(node.argument);
4018
+ if (options.async && isAwaitable(arg)) {
4019
+ return arg.awaitableThen(function(argVal) {
4020
+ return operator1(argVal, isAsync);
4021
+ });
4022
+ }
4023
+ return operator1(arg, isAsync);
3804
4024
  }
3805
4025
  return;
3806
4026
  }
3807
4027
  if (node.type === "Object") {
3808
- var attributes = node.attributes;
3809
- var resolvedAttributes = {};
3810
- attributes.forEach(function(attr) {
3811
- var key = resolveNode(attr.key);
3812
- var value = resolveNode(attr.value);
3813
- resolvedAttributes[key] = value;
3814
- });
3815
- return resolvedAttributes;
4028
+ return PromiseCollectionHandler.handleObject(node.attributes, resolveNode, options.async || false);
3816
4029
  }
3817
4030
  if (node.type === "CallExpression") {
3818
4031
  var expressionName = node.callTarget.name;
@@ -3820,6 +4033,9 @@ var StageRevertDataPlugin = function() {
3820
4033
  if (!operator2) {
3821
4034
  throw new Error("Unknown expression function: ".concat(expressionName));
3822
4035
  }
4036
+ if (operator2.name === waitFor.name && !options.async) {
4037
+ throw new Error("Usage of await outside of async context");
4038
+ }
3823
4039
  if ("resolveParams" in operator2 && operator2.resolveParams === false) {
3824
4040
  return operator2.apply(void 0, [
3825
4041
  expressionContext
@@ -3828,6 +4044,16 @@ var StageRevertDataPlugin = function() {
3828
4044
  var args = node.args.map(function(n) {
3829
4045
  return resolveNode(n);
3830
4046
  });
4047
+ if (options.async) {
4048
+ var hasPromises = args.some(isAwaitable);
4049
+ if (hasPromises) {
4050
+ return collateAwaitable(args).awaitableThen(function(resolvedArgs) {
4051
+ return operator2.apply(void 0, [
4052
+ expressionContext
4053
+ ].concat(_to_consumable_array(resolvedArgs)));
4054
+ });
4055
+ }
4056
+ }
3831
4057
  return operator2.apply(void 0, [
3832
4058
  expressionContext
3833
4059
  ].concat(_to_consumable_array(args)));
@@ -3842,11 +4068,36 @@ var StageRevertDataPlugin = function() {
3842
4068
  if (node.type === "MemberExpression") {
3843
4069
  var obj = resolveNode(node.object);
3844
4070
  var prop = resolveNode(node.property);
4071
+ if (options.async && (isAwaitable(obj) || isAwaitable(prop))) {
4072
+ return collateAwaitable([
4073
+ obj,
4074
+ prop
4075
+ ]).awaitableThen(function(param) {
4076
+ var _param = _sliced_to_array(param, 2), objVal = _param[0], propVal = _param[1];
4077
+ return objVal[propVal];
4078
+ });
4079
+ }
3845
4080
  return obj[prop];
3846
4081
  }
3847
4082
  if (node.type === "Assignment") {
3848
4083
  if (node.left.type === "ModelRef") {
3849
4084
  var value = resolveNode(node.right);
4085
+ if (isPromiseLike(value)) {
4086
+ if (options.async && isAwaitable(value)) {
4087
+ return value.awaitableThen(function(resolvedValue) {
4088
+ model.set([
4089
+ [
4090
+ node.left.ref,
4091
+ resolvedValue
4092
+ ]
4093
+ ]);
4094
+ return resolvedValue;
4095
+ });
4096
+ } else {
4097
+ var _options_logger;
4098
+ (_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");
4099
+ }
4100
+ }
3850
4101
  model.set([
3851
4102
  [
3852
4103
  node.left.ref,
@@ -3857,19 +4108,30 @@ var StageRevertDataPlugin = function() {
3857
4108
  }
3858
4109
  if (node.left.type === "Identifier") {
3859
4110
  var value1 = resolveNode(node.right);
4111
+ if (options.async && isAwaitable(value1)) {
4112
+ return value1.awaitableThen(function(resolvedValue) {
4113
+ _this.vars[node.left.name] = resolvedValue;
4114
+ return resolvedValue;
4115
+ });
4116
+ }
3860
4117
  this.vars[node.left.name] = value1;
3861
4118
  return value1;
3862
4119
  }
3863
4120
  return;
3864
4121
  }
3865
4122
  if (node.type === "ConditionalExpression") {
3866
- var result = resolveNode(node.test) ? node.consequent : node.alternate;
3867
- return resolveNode(result);
4123
+ var testResult = resolveNode(node.test);
4124
+ return handleConditionalBranching(testResult, function() {
4125
+ return node.consequent;
4126
+ }, function() {
4127
+ return node.alternate;
4128
+ }, resolveNode, isAsync);
3868
4129
  }
3869
4130
  if (node.type === "ArrayExpression") {
3870
- return node.elements.map(function(ele) {
4131
+ var results = node.elements.map(function(ele) {
3871
4132
  return resolveNode(ele);
3872
4133
  });
4134
+ return PromiseCollectionHandler.handleArray(results, isAsync);
3873
4135
  }
3874
4136
  if (node.type === "Modification") {
3875
4137
  var operation = this.operators.binary.get(node.operator);
@@ -3877,14 +4139,49 @@ var StageRevertDataPlugin = function() {
3877
4139
  var newValue;
3878
4140
  if ("resolveParams" in operation) {
3879
4141
  if (operation.resolveParams === false) {
3880
- newValue = operation(expressionContext, node.left, node.right);
4142
+ newValue = operation(expressionContext, node.left, node.right, isAsync);
3881
4143
  } else {
3882
- newValue = operation(expressionContext, resolveNode(node.left), resolveNode(node.right));
4144
+ var left1 = resolveNode(node.left);
4145
+ var right1 = resolveNode(node.right);
4146
+ if (options.async && (isAwaitable(left1) || isAwaitable(right1))) {
4147
+ newValue = collateAwaitable([
4148
+ left1,
4149
+ right1
4150
+ ]).awaitableThen(function(param) {
4151
+ var _param = _sliced_to_array(param, 2), leftVal = _param[0], rightVal = _param[1];
4152
+ return operation(expressionContext, leftVal, rightVal, isAsync);
4153
+ });
4154
+ } else {
4155
+ newValue = operation(expressionContext, left1, right1, isAsync);
4156
+ }
3883
4157
  }
3884
4158
  } else {
3885
- newValue = operation(resolveNode(node.left), resolveNode(node.right));
4159
+ var left3 = resolveNode(node.left);
4160
+ var right3 = resolveNode(node.right);
4161
+ if (options.async && (isAwaitable(left3) || isAwaitable(right3))) {
4162
+ newValue = collateAwaitable([
4163
+ left3,
4164
+ right3
4165
+ ]).awaitableThen(function(param) {
4166
+ var _param = _sliced_to_array(param, 2), leftVal = _param[0], rightVal = _param[1];
4167
+ return operation(leftVal, rightVal, isAsync);
4168
+ });
4169
+ } else {
4170
+ newValue = operation(left3, right3, isAsync);
4171
+ }
3886
4172
  }
3887
4173
  if (node.left.type === "ModelRef") {
4174
+ if (options.async && isAwaitable(newValue)) {
4175
+ return newValue.awaitableThen(function(resolvedValue) {
4176
+ model.set([
4177
+ [
4178
+ node.left.ref,
4179
+ resolvedValue
4180
+ ]
4181
+ ]);
4182
+ return resolvedValue;
4183
+ });
4184
+ }
3888
4185
  model.set([
3889
4186
  [
3890
4187
  node.left.ref,
@@ -3892,6 +4189,12 @@ var StageRevertDataPlugin = function() {
3892
4189
  ]
3893
4190
  ]);
3894
4191
  } else if (node.left.type === "Identifier") {
4192
+ if (options.async && isAwaitable(newValue)) {
4193
+ return newValue.awaitableThen(function(resolvedValue) {
4194
+ _this.vars[node.left.name] = resolvedValue;
4195
+ return resolvedValue;
4196
+ });
4197
+ }
3895
4198
  this.vars[node.left.name] = newValue;
3896
4199
  }
3897
4200
  return newValue;
@@ -4757,20 +5060,15 @@ var StageRevertDataPlugin = function() {
4757
5060
  }();
4758
5061
  var ViewInstance = /*#__PURE__*/ function() {
4759
5062
  function ViewInstance(initialView, resolverOptions) {
4760
- var _this = this;
4761
5063
  _class_call_check(this, ViewInstance);
4762
5064
  this.hooks = {
4763
5065
  onUpdate: new SyncHook(),
4764
5066
  parser: new SyncHook(),
4765
5067
  resolver: new SyncHook(),
4766
- onTemplatePluginCreated: new SyncHook(),
4767
5068
  templatePlugin: new SyncHook()
4768
5069
  };
4769
5070
  this.initialView = initialView;
4770
5071
  this.resolverOptions = resolverOptions;
4771
- this.hooks.onTemplatePluginCreated.tap("view", function(templatePlugin) {
4772
- _this.templatePlugin = templatePlugin;
4773
- });
4774
5072
  }
4775
5073
  _create_class(ViewInstance, [
4776
5074
  {
@@ -4817,6 +5115,12 @@ var StageRevertDataPlugin = function() {
4817
5115
  var _this_validationProvider;
4818
5116
  return (_this_validationProvider = this.validationProvider) === null || _this_validationProvider === void 0 ? void 0 : _this_validationProvider.getValidationsForBinding(binding);
4819
5117
  }
5118
+ },
5119
+ {
5120
+ key: "setTemplatePlugin",
5121
+ value: function setTemplatePlugin(plugin) {
5122
+ this.templatePlugin = plugin;
5123
+ }
4820
5124
  }
4821
5125
  ]);
4822
5126
  return ViewInstance;
@@ -4988,6 +5292,7 @@ var StageRevertDataPlugin = function() {
4988
5292
  value: function apply(view) {
4989
5293
  view.hooks.parser.tap("template", this.applyParser.bind(this));
4990
5294
  view.hooks.resolver.tap("template", this.applyResolverHooks.bind(this));
5295
+ view.setTemplatePlugin(this);
4991
5296
  }
4992
5297
  }
4993
5298
  ]);
@@ -6596,8 +6901,7 @@ var StageRevertDataPlugin = function() {
6596
6901
  var _this1 = this;
6597
6902
  _class_call_check(this, ViewController);
6598
6903
  this.hooks = {
6599
- /** Do any processing before the `View` instance is created */ resolveView: new SyncWaterfallHook(),
6600
- // The hook right before the View starts resolving. Attach anything custom here
6904
+ resolveView: new SyncWaterfallHook(),
6601
6905
  view: new SyncHook()
6602
6906
  };
6603
6907
  this.transformRegistry = new Registry();
@@ -6645,6 +6949,7 @@ var StageRevertDataPlugin = function() {
6645
6949
  ]));
6646
6950
  }
6647
6951
  });
6952
+ this.viewPlugins = this.createViewPlugins();
6648
6953
  }
6649
6954
  _create_class(ViewController, [
6650
6955
  {
@@ -6700,9 +7005,50 @@ var StageRevertDataPlugin = function() {
6700
7005
  }
6701
7006
  var view = new ViewInstance(source, this.viewOptions);
6702
7007
  this.currentView = view;
7008
+ this.applyViewPlugins(view);
6703
7009
  this.hooks.view.call(view);
6704
7010
  view.update();
6705
7011
  }
7012
+ },
7013
+ {
7014
+ key: "applyViewPlugins",
7015
+ value: function applyViewPlugins(view) {
7016
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
7017
+ try {
7018
+ for(var _iterator = this.viewPlugins[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
7019
+ var plugin = _step.value;
7020
+ plugin.apply(view);
7021
+ }
7022
+ } catch (err) {
7023
+ _didIteratorError = true;
7024
+ _iteratorError = err;
7025
+ } finally{
7026
+ try {
7027
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
7028
+ _iterator.return();
7029
+ }
7030
+ } finally{
7031
+ if (_didIteratorError) {
7032
+ throw _iteratorError;
7033
+ }
7034
+ }
7035
+ }
7036
+ }
7037
+ },
7038
+ {
7039
+ key: "createViewPlugins",
7040
+ value: function createViewPlugins() {
7041
+ var pluginOptions = toNodeResolveOptions(this.viewOptions);
7042
+ return [
7043
+ new AssetPlugin(),
7044
+ new SwitchPlugin(pluginOptions),
7045
+ new ApplicabilityPlugin(),
7046
+ new AssetTransformCorePlugin(this.transformRegistry),
7047
+ new StringResolverPlugin(),
7048
+ new TemplatePlugin(pluginOptions),
7049
+ new MultiNodePlugin()
7050
+ ];
7051
+ }
6706
7052
  }
6707
7053
  ]);
6708
7054
  return ViewController;
@@ -7075,35 +7421,6 @@ var StageRevertDataPlugin = function() {
7075
7421
  ref: Symbol("not-started"),
7076
7422
  status: "not-started"
7077
7423
  };
7078
- var DefaultViewPlugin = /*#__PURE__*/ function() {
7079
- function DefaultViewPlugin() {
7080
- _class_call_check(this, DefaultViewPlugin);
7081
- this.name = "default-view-plugin";
7082
- }
7083
- _create_class(DefaultViewPlugin, [
7084
- {
7085
- key: "apply",
7086
- value: function apply(player) {
7087
- var _this = this;
7088
- player.hooks.viewController.tap(this.name, function(viewController) {
7089
- viewController.hooks.view.tap(_this.name, function(view) {
7090
- var pluginOptions = toNodeResolveOptions(view.resolverOptions);
7091
- new AssetPlugin().apply(view);
7092
- new SwitchPlugin(pluginOptions).apply(view);
7093
- new ApplicabilityPlugin().apply(view);
7094
- new AssetTransformCorePlugin(viewController.transformRegistry).apply(view);
7095
- new StringResolverPlugin().apply(view);
7096
- var templatePlugin = new TemplatePlugin(pluginOptions);
7097
- templatePlugin.apply(view);
7098
- view.hooks.onTemplatePluginCreated.call(templatePlugin);
7099
- new MultiNodePlugin().apply(view);
7100
- });
7101
- });
7102
- }
7103
- }
7104
- ]);
7105
- return DefaultViewPlugin;
7106
- }();
7107
7424
  var PLAYER_VERSION = "__VERSION__";
7108
7425
  var COMMIT = "__GIT_COMMIT__";
7109
7426
  var _Player = /*#__PURE__*/ function() {
@@ -7115,26 +7432,25 @@ var StageRevertDataPlugin = function() {
7115
7432
  this.constantsController = new ConstantsController();
7116
7433
  this.state = NOT_STARTED_STATE;
7117
7434
  this.hooks = {
7118
- /** The hook that fires every time we create a new flowController (a new Content blob is passed in) */ flowController: new SyncHook(),
7119
- /** The hook that updates/handles views */ viewController: new SyncHook(),
7120
- /** A hook called every-time there's a new view. This is equivalent to the view hook on the view-controller */ view: new SyncHook(),
7121
- /** Called when an expression evaluator was created */ expressionEvaluator: new SyncHook(),
7122
- /** The hook that creates and manages data */ dataController: new SyncHook(),
7123
- /** Called after the schema is created for a flow */ schema: new SyncHook(),
7124
- /** Manages validations (schema and x-field ) */ validationController: new SyncHook(),
7125
- /** Manages parsing binding */ bindingParser: new SyncHook(),
7126
- /** A that's called for state changes in the flow execution */ state: new SyncHook(),
7127
- /** A hook to access the current flow */ onStart: new SyncHook(),
7128
- /** A hook for when the flow ends either in success or failure */ onEnd: new SyncHook(),
7129
- /** Mutate the Content flow before starting */ resolveFlowContent: new SyncWaterfallHook()
7435
+ flowController: new SyncHook(),
7436
+ viewController: new SyncHook(),
7437
+ view: new SyncHook(),
7438
+ expressionEvaluator: new SyncHook(),
7439
+ dataController: new SyncHook(),
7440
+ schema: new SyncHook(),
7441
+ validationController: new SyncHook(),
7442
+ bindingParser: new SyncHook(),
7443
+ state: new SyncHook(),
7444
+ onStart: new SyncHook(),
7445
+ onEnd: new SyncHook(),
7446
+ resolveFlowContent: new SyncWaterfallHook()
7130
7447
  };
7131
7448
  if (config === null || config === void 0 ? void 0 : config.logger) {
7132
7449
  this.logger.addHandler(config.logger);
7133
7450
  }
7134
7451
  this.config = config || {};
7135
7452
  this.config.plugins = [
7136
- new DefaultExpPlugin(),
7137
- new DefaultViewPlugin()
7453
+ new DefaultExpPlugin()
7138
7454
  ].concat(_to_consumable_array(this.config.plugins || []), [
7139
7455
  new FlowExpPlugin()
7140
7456
  ]);
@@ -7326,10 +7642,90 @@ var StageRevertDataPlugin = function() {
7326
7642
  var value = (_flowInstance_currentState = flowInstance.currentState) === null || _flowInstance_currentState === void 0 ? void 0 : _flowInstance_currentState.value;
7327
7643
  if (value && value.state_type === "ACTION") {
7328
7644
  var exp = value.exp;
7329
- flowController === null || flowController === void 0 ? void 0 : flowController.transition(String(expressionEvaluator === null || expressionEvaluator === void 0 ? void 0 : expressionEvaluator.evaluate(exp)));
7645
+ var result = expressionEvaluator.evaluate(exp);
7646
+ if (isPromiseLike(result)) {
7647
+ _this.logger.warn("Async expression used as return value in in non-async context, transitioning with '*' value");
7648
+ }
7649
+ flowController === null || flowController === void 0 ? void 0 : flowController.transition(String(result));
7330
7650
  }
7331
7651
  expressionEvaluator.reset();
7332
7652
  });
7653
+ var _this1 = _this;
7654
+ flow.hooks.afterTransition.tap("player", function() {
7655
+ var _ref = _async_to_generator(function(flowInstance) {
7656
+ var _flowInstance_currentState, value, exp, result, e;
7657
+ return _ts_generator(this, function(_state) {
7658
+ switch(_state.label){
7659
+ case 0:
7660
+ value = (_flowInstance_currentState = flowInstance.currentState) === null || _flowInstance_currentState === void 0 ? void 0 : _flowInstance_currentState.value;
7661
+ if (!(value && value.state_type === "ASYNC_ACTION")) return [
7662
+ 3,
7663
+ 8
7664
+ ];
7665
+ exp = value.exp;
7666
+ _state.label = 1;
7667
+ case 1:
7668
+ _state.trys.push([
7669
+ 1,
7670
+ 7,
7671
+ ,
7672
+ 8
7673
+ ]);
7674
+ result = expressionEvaluator.evaluateAsync(exp);
7675
+ if (!isPromiseLike(result)) return [
7676
+ 3,
7677
+ 5
7678
+ ];
7679
+ if (!value.await) return [
7680
+ 3,
7681
+ 3
7682
+ ];
7683
+ return [
7684
+ 4,
7685
+ result
7686
+ ];
7687
+ case 2:
7688
+ result = _state.sent();
7689
+ return [
7690
+ 3,
7691
+ 4
7692
+ ];
7693
+ case 3:
7694
+ _this1.logger.warn("Unawaited promise used as return value in in non-async context, transitioning with '*' value");
7695
+ _state.label = 4;
7696
+ case 4:
7697
+ return [
7698
+ 3,
7699
+ 6
7700
+ ];
7701
+ case 5:
7702
+ _this1.logger.warn("Non async expression used in async action node");
7703
+ _state.label = 6;
7704
+ case 6:
7705
+ flowController === null || flowController === void 0 ? void 0 : flowController.transition(String(result));
7706
+ return [
7707
+ 3,
7708
+ 8
7709
+ ];
7710
+ case 7:
7711
+ e = _state.sent();
7712
+ flowResultDeferred.reject(e);
7713
+ return [
7714
+ 3,
7715
+ 8
7716
+ ];
7717
+ case 8:
7718
+ expressionEvaluator.reset();
7719
+ return [
7720
+ 2
7721
+ ];
7722
+ }
7723
+ });
7724
+ });
7725
+ return function(flowInstance) {
7726
+ return _ref.apply(this, arguments);
7727
+ };
7728
+ }());
7333
7729
  });
7334
7730
  this.hooks.dataController.call(dataController);
7335
7731
  validationController.setOptions({
@@ -7367,11 +7763,9 @@ var StageRevertDataPlugin = function() {
7367
7763
  }),
7368
7764
  constants: this.constantsController
7369
7765
  });
7370
- this.hooks.viewController.tap("player", function(vc) {
7371
- vc.hooks.view.tap("player", function(view) {
7372
- validationController.onView(view);
7373
- _this.hooks.view.call(view);
7374
- });
7766
+ viewController.hooks.view.tap("player", function(view) {
7767
+ validationController.onView(view);
7768
+ _this.hooks.view.call(view);
7375
7769
  });
7376
7770
  this.hooks.viewController.call(viewController);
7377
7771
  return {