@player-ui/async-node-plugin 0.12.0--canary.660.23287 → 0.12.0--canary.649.24150

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);
4053
+ }
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
+ });
3859
4064
  }
3860
- return operator(resolveNode(node.left), resolveNode(node.right));
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);
4083
+ }
4084
+ var arg = resolveNode(node.argument);
4085
+ if (options.async && isAwaitable(arg)) {
4086
+ return arg.awaitableThen(function(argVal) {
4087
+ return operator1(argVal, isAsync);
4088
+ });
3869
4089
  }
3870
- return operator1(resolveNode(node.argument));
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" && !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;
@@ -5596,6 +5899,178 @@ var AsyncNodePlugin = function() {
5596
5899
  ]);
5597
5900
  return AssetPlugin;
5598
5901
  }();
5902
+ var LocalStateStore = /*#__PURE__*/ function() {
5903
+ function LocalStateStore(onUpdate) {
5904
+ _class_call_check(this, LocalStateStore);
5905
+ this.updateCallback = onUpdate;
5906
+ this.state = /* @__PURE__ */ new Map();
5907
+ }
5908
+ _create_class(LocalStateStore, [
5909
+ {
5910
+ key: "removeKey",
5911
+ value: function removeKey(key) {
5912
+ this.state.delete(key);
5913
+ }
5914
+ },
5915
+ {
5916
+ key: "reset",
5917
+ value: function reset() {
5918
+ this.state.clear();
5919
+ }
5920
+ },
5921
+ {
5922
+ key: "useSharedState",
5923
+ value: function useSharedState(key) {
5924
+ var _this = this;
5925
+ return function(initialState) {
5926
+ if (!_this.state.has(key)) {
5927
+ _this.state.set(key, initialState);
5928
+ }
5929
+ return [
5930
+ _this.state.get(key),
5931
+ function(newState) {
5932
+ var current = _this.state.get(key);
5933
+ _this.state.set(key, newState);
5934
+ if (current !== newState) {
5935
+ var _this_updateCallback, _this1;
5936
+ (_this_updateCallback = (_this1 = _this).updateCallback) === null || _this_updateCallback === void 0 ? void 0 : _this_updateCallback.call(_this1);
5937
+ }
5938
+ }
5939
+ ];
5940
+ };
5941
+ }
5942
+ },
5943
+ {
5944
+ key: "getLocalStateFunction",
5945
+ value: function getLocalStateFunction(key, countKey) {
5946
+ var _this = this;
5947
+ return function(initialState) {
5948
+ if (!_this.state.has(key)) {
5949
+ _this.state.set(key, []);
5950
+ }
5951
+ if (!_this.state.has(countKey)) {
5952
+ _this.state.set(countKey, 0);
5953
+ }
5954
+ var localState = _this.state.get(key);
5955
+ var oldCount = _this.state.get(countKey);
5956
+ _this.state.set(countKey, oldCount + 1);
5957
+ if (localState.length <= oldCount) {
5958
+ localState.push(initialState);
5959
+ }
5960
+ var value = localState[oldCount];
5961
+ return [
5962
+ value,
5963
+ function(newState) {
5964
+ var oldValue = localState[oldCount];
5965
+ localState[oldCount] = newState;
5966
+ if (oldValue !== newState) {
5967
+ var _this_updateCallback, _this1;
5968
+ (_this_updateCallback = (_this1 = _this).updateCallback) === null || _this_updateCallback === void 0 ? void 0 : _this_updateCallback.call(_this1);
5969
+ }
5970
+ }
5971
+ ];
5972
+ };
5973
+ }
5974
+ }
5975
+ ]);
5976
+ return LocalStateStore;
5977
+ }();
5978
+ function findUp(node, target) {
5979
+ if (node === target) {
5980
+ return true;
5981
+ }
5982
+ if (node.parent) {
5983
+ return findUp(node.parent, target);
5984
+ }
5985
+ return false;
5986
+ }
5987
+ var AssetTransformCorePlugin = /*#__PURE__*/ function() {
5988
+ function AssetTransformCorePlugin(registry) {
5989
+ _class_call_check(this, AssetTransformCorePlugin);
5990
+ this.registry = registry;
5991
+ this.stateStore = /* @__PURE__ */ new Map();
5992
+ this.beforeResolveSymbol = Symbol("before resolve");
5993
+ this.resolveSymbol = Symbol("resolve");
5994
+ this.beforeResolveCountSymbol = Symbol("before resolve count");
5995
+ this.resolveCountSymbol = Symbol("resolve count");
5996
+ }
5997
+ _create_class(AssetTransformCorePlugin, [
5998
+ {
5999
+ key: "apply",
6000
+ value: function apply(view) {
6001
+ var _this = this;
6002
+ this.stateStore.clear();
6003
+ view.hooks.resolver.tap("asset-transform", function(resolver) {
6004
+ var lastUpdatedNode;
6005
+ var updateState = function(node) {
6006
+ lastUpdatedNode = node;
6007
+ view.update(/* @__PURE__ */ new Set());
6008
+ };
6009
+ var getStore = function(node, stepKey) {
6010
+ var store;
6011
+ var countKey = stepKey === _this.resolveSymbol ? _this.resolveCountSymbol : _this.beforeResolveCountSymbol;
6012
+ var storedState = _this.stateStore.get(node);
6013
+ if (storedState) {
6014
+ store = storedState;
6015
+ store.removeKey(countKey);
6016
+ } else {
6017
+ store = new LocalStateStore(function() {
6018
+ updateState(node);
6019
+ });
6020
+ _this.stateStore.set(node, store);
6021
+ }
6022
+ return {
6023
+ useSharedState: function(key) {
6024
+ return store.useSharedState(key);
6025
+ },
6026
+ useLocalState: function(initialState) {
6027
+ return store.getLocalStateFunction(stepKey, countKey)(initialState);
6028
+ }
6029
+ };
6030
+ };
6031
+ resolver.hooks.beforeResolve.tap("asset-transform", function(node, options) {
6032
+ if (node && (node.type === "asset" || node.type === "view")) {
6033
+ var transform = _this.registry.get(node.value);
6034
+ if (transform === null || transform === void 0 ? void 0 : transform.beforeResolve) {
6035
+ var _options_node;
6036
+ var store = getStore((_options_node = options.node) !== null && _options_node !== void 0 ? _options_node : node, _this.beforeResolveSymbol);
6037
+ return transform.beforeResolve(node, options, store);
6038
+ }
6039
+ }
6040
+ return node;
6041
+ });
6042
+ resolver.hooks.afterUpdate.tap("asset-transform", function() {
6043
+ lastUpdatedNode = void 0;
6044
+ });
6045
+ resolver.hooks.skipResolve.tap("asset-transform", function(skip, node) {
6046
+ if (!skip || !lastUpdatedNode) {
6047
+ return skip;
6048
+ }
6049
+ var isParentOfUpdated = findUp(lastUpdatedNode, node);
6050
+ var isChildOfUpdated = findUp(node, lastUpdatedNode);
6051
+ return !isParentOfUpdated && !isChildOfUpdated;
6052
+ });
6053
+ resolver.hooks.afterResolve.tap("asset-transform", function(value, node, options) {
6054
+ if (node.type !== "asset" && node.type !== "view") {
6055
+ return value;
6056
+ }
6057
+ var originalNode = resolver.getSourceNode(node);
6058
+ if (!originalNode) {
6059
+ return value;
6060
+ }
6061
+ var transform = _this.registry.get(value);
6062
+ if (transform === null || transform === void 0 ? void 0 : transform.resolve) {
6063
+ var store = getStore(originalNode, _this.resolveSymbol);
6064
+ return transform === null || transform === void 0 ? void 0 : transform.resolve(value, options, store);
6065
+ }
6066
+ return value;
6067
+ });
6068
+ });
6069
+ }
6070
+ }
6071
+ ]);
6072
+ return AssetTransformCorePlugin;
6073
+ }();
5599
6074
  var FlowInstance = /*#__PURE__*/ function() {
5600
6075
  function FlowInstance(id, flow, options) {
5601
6076
  _class_call_check(this, FlowInstance);
@@ -6625,180 +7100,6 @@ var AsyncNodePlugin = function() {
6625
7100
  ]);
6626
7101
  return ValidationController;
6627
7102
  }();
6628
- var LocalStateStore = /*#__PURE__*/ function() {
6629
- function LocalStateStore(onUpdate) {
6630
- _class_call_check(this, LocalStateStore);
6631
- this.updateCallback = onUpdate;
6632
- this.state = /* @__PURE__ */ new Map();
6633
- }
6634
- _create_class(LocalStateStore, [
6635
- {
6636
- key: "removeKey",
6637
- value: function removeKey(key) {
6638
- this.state.delete(key);
6639
- }
6640
- },
6641
- {
6642
- key: "reset",
6643
- value: function reset() {
6644
- this.state.clear();
6645
- }
6646
- },
6647
- {
6648
- key: "useSharedState",
6649
- value: function useSharedState(key) {
6650
- var _this = this;
6651
- return function(initialState) {
6652
- if (!_this.state.has(key)) {
6653
- _this.state.set(key, initialState);
6654
- }
6655
- return [
6656
- _this.state.get(key),
6657
- function(newState) {
6658
- var current = _this.state.get(key);
6659
- _this.state.set(key, newState);
6660
- if (current !== newState) {
6661
- var _this_updateCallback, _this1;
6662
- (_this_updateCallback = (_this1 = _this).updateCallback) === null || _this_updateCallback === void 0 ? void 0 : _this_updateCallback.call(_this1);
6663
- }
6664
- }
6665
- ];
6666
- };
6667
- }
6668
- },
6669
- {
6670
- key: "getLocalStateFunction",
6671
- value: function getLocalStateFunction(key, countKey) {
6672
- var _this = this;
6673
- return function(initialState) {
6674
- if (!_this.state.has(key)) {
6675
- _this.state.set(key, []);
6676
- }
6677
- if (!_this.state.has(countKey)) {
6678
- _this.state.set(countKey, 0);
6679
- }
6680
- var localState = _this.state.get(key);
6681
- var oldCount = _this.state.get(countKey);
6682
- _this.state.set(countKey, oldCount + 1);
6683
- if (localState.length <= oldCount) {
6684
- localState.push(initialState);
6685
- }
6686
- var value = localState[oldCount];
6687
- return [
6688
- value,
6689
- function(newState) {
6690
- var oldValue = localState[oldCount];
6691
- localState[oldCount] = newState;
6692
- if (oldValue !== newState) {
6693
- var _this_updateCallback, _this1;
6694
- (_this_updateCallback = (_this1 = _this).updateCallback) === null || _this_updateCallback === void 0 ? void 0 : _this_updateCallback.call(_this1);
6695
- }
6696
- }
6697
- ];
6698
- };
6699
- }
6700
- }
6701
- ]);
6702
- return LocalStateStore;
6703
- }();
6704
- function findUp(node, target) {
6705
- if (node === target) {
6706
- return true;
6707
- }
6708
- if (node.parent) {
6709
- return findUp(node.parent, target);
6710
- }
6711
- return false;
6712
- }
6713
- var AssetTransformCorePlugin = /*#__PURE__*/ function() {
6714
- function AssetTransformCorePlugin(registry) {
6715
- _class_call_check(this, AssetTransformCorePlugin);
6716
- this.registry = registry;
6717
- this.stateStore = /* @__PURE__ */ new Map();
6718
- this.beforeResolveSymbol = Symbol("before resolve");
6719
- this.resolveSymbol = Symbol("resolve");
6720
- this.beforeResolveCountSymbol = Symbol("before resolve count");
6721
- this.resolveCountSymbol = Symbol("resolve count");
6722
- }
6723
- _create_class(AssetTransformCorePlugin, [
6724
- {
6725
- key: "apply",
6726
- value: function apply(viewController) {
6727
- var _this = this;
6728
- viewController.hooks.view.tap("asset-transform", function(view) {
6729
- _this.stateStore.clear();
6730
- view.hooks.resolver.tap("asset-transform", function(resolver) {
6731
- var lastUpdatedNode;
6732
- var updateState = function(node) {
6733
- lastUpdatedNode = node;
6734
- view.update(/* @__PURE__ */ new Set());
6735
- };
6736
- var getStore = function(node, stepKey) {
6737
- var store;
6738
- var countKey = stepKey === _this.resolveSymbol ? _this.resolveCountSymbol : _this.beforeResolveCountSymbol;
6739
- var storedState = _this.stateStore.get(node);
6740
- if (storedState) {
6741
- store = storedState;
6742
- store.removeKey(countKey);
6743
- } else {
6744
- store = new LocalStateStore(function() {
6745
- updateState(node);
6746
- });
6747
- _this.stateStore.set(node, store);
6748
- }
6749
- return {
6750
- useSharedState: function(key) {
6751
- return store.useSharedState(key);
6752
- },
6753
- useLocalState: function(initialState) {
6754
- return store.getLocalStateFunction(stepKey, countKey)(initialState);
6755
- }
6756
- };
6757
- };
6758
- resolver.hooks.beforeResolve.tap("asset-transform", function(node, options) {
6759
- if (node && (node.type === "asset" || node.type === "view")) {
6760
- var transform = _this.registry.get(node.value);
6761
- if (transform === null || transform === void 0 ? void 0 : transform.beforeResolve) {
6762
- var _options_node;
6763
- var store = getStore((_options_node = options.node) !== null && _options_node !== void 0 ? _options_node : node, _this.beforeResolveSymbol);
6764
- return transform.beforeResolve(node, options, store);
6765
- }
6766
- }
6767
- return node;
6768
- });
6769
- resolver.hooks.afterUpdate.tap("asset-transform", function() {
6770
- lastUpdatedNode = void 0;
6771
- });
6772
- resolver.hooks.skipResolve.tap("asset-transform", function(skip, node) {
6773
- if (!skip || !lastUpdatedNode) {
6774
- return skip;
6775
- }
6776
- var isParentOfUpdated = findUp(lastUpdatedNode, node);
6777
- var isChildOfUpdated = findUp(node, lastUpdatedNode);
6778
- return !isParentOfUpdated && !isChildOfUpdated;
6779
- });
6780
- resolver.hooks.afterResolve.tap("asset-transform", function(value, node, options) {
6781
- if (node.type !== "asset" && node.type !== "view") {
6782
- return value;
6783
- }
6784
- var originalNode = resolver.getSourceNode(node);
6785
- if (!originalNode) {
6786
- return value;
6787
- }
6788
- var transform = _this.registry.get(value);
6789
- if (transform === null || transform === void 0 ? void 0 : transform.resolve) {
6790
- var store = getStore(originalNode, _this.resolveSymbol);
6791
- return transform === null || transform === void 0 ? void 0 : transform.resolve(value, options, store);
6792
- }
6793
- return value;
6794
- });
6795
- });
6796
- });
6797
- }
6798
- }
6799
- ]);
6800
- return AssetTransformCorePlugin;
6801
- }();
6802
7103
  var ViewController = /*#__PURE__*/ function() {
6803
7104
  function ViewController(initialViews, options) {
6804
7105
  var _this = this;
@@ -6816,7 +7117,6 @@ var AsyncNodePlugin = function() {
6816
7117
  viewMap[view.id] = view;
6817
7118
  return viewMap;
6818
7119
  }, {});
6819
- new AssetTransformCorePlugin(this.transformRegistry).apply(this);
6820
7120
  options.flowController.hooks.flow.tap("viewController", function(flow) {
6821
7121
  flow.hooks.transition.tap("viewController", function(_oldState, newState) {
6822
7122
  if (newState.value.state_type === "VIEW") {
@@ -7301,6 +7601,7 @@ var AsyncNodePlugin = function() {
7301
7601
  new AssetPlugin().apply(view);
7302
7602
  new SwitchPlugin(pluginOptions).apply(view);
7303
7603
  new ApplicabilityPlugin().apply(view);
7604
+ new AssetTransformCorePlugin(viewController.transformRegistry).apply(view);
7304
7605
  new StringResolverPlugin().apply(view);
7305
7606
  var templatePlugin = new TemplatePlugin(pluginOptions);
7306
7607
  templatePlugin.apply(view);
@@ -7535,10 +7836,90 @@ var AsyncNodePlugin = function() {
7535
7836
  var value = (_flowInstance_currentState = flowInstance.currentState) === null || _flowInstance_currentState === void 0 ? void 0 : _flowInstance_currentState.value;
7536
7837
  if (value && value.state_type === "ACTION") {
7537
7838
  var exp = value.exp;
7538
- flowController === null || flowController === void 0 ? void 0 : flowController.transition(String(expressionEvaluator === null || expressionEvaluator === void 0 ? void 0 : expressionEvaluator.evaluate(exp)));
7839
+ var result = expressionEvaluator.evaluate(exp);
7840
+ if (isPromiselike(result)) {
7841
+ _this.logger.warn("Async expression used as return value in in non-async context, transitioning with '*' value");
7842
+ }
7843
+ flowController === null || flowController === void 0 ? void 0 : flowController.transition(String(result));
7539
7844
  }
7540
7845
  expressionEvaluator.reset();
7541
7846
  });
7847
+ var _this1 = _this;
7848
+ flow.hooks.afterTransition.tap("player", function() {
7849
+ var _ref = _async_to_generator(function(flowInstance) {
7850
+ var _flowInstance_currentState, value, exp, result, e;
7851
+ return _ts_generator(this, function(_state) {
7852
+ switch(_state.label){
7853
+ case 0:
7854
+ value = (_flowInstance_currentState = flowInstance.currentState) === null || _flowInstance_currentState === void 0 ? void 0 : _flowInstance_currentState.value;
7855
+ if (!(value && value.state_type === "ASYNC_ACTION")) return [
7856
+ 3,
7857
+ 8
7858
+ ];
7859
+ exp = value.exp;
7860
+ _state.label = 1;
7861
+ case 1:
7862
+ _state.trys.push([
7863
+ 1,
7864
+ 7,
7865
+ ,
7866
+ 8
7867
+ ]);
7868
+ result = expressionEvaluator.evaluateAsync(exp);
7869
+ if (!isPromiselike(result)) return [
7870
+ 3,
7871
+ 5
7872
+ ];
7873
+ if (!value.await) return [
7874
+ 3,
7875
+ 3
7876
+ ];
7877
+ return [
7878
+ 4,
7879
+ result
7880
+ ];
7881
+ case 2:
7882
+ result = _state.sent();
7883
+ return [
7884
+ 3,
7885
+ 4
7886
+ ];
7887
+ case 3:
7888
+ _this1.logger.warn("Unawaited promise used as return value in in non-async context, transitioning with '*' value");
7889
+ _state.label = 4;
7890
+ case 4:
7891
+ return [
7892
+ 3,
7893
+ 6
7894
+ ];
7895
+ case 5:
7896
+ _this1.logger.warn("Non async expression used in async action node");
7897
+ _state.label = 6;
7898
+ case 6:
7899
+ flowController === null || flowController === void 0 ? void 0 : flowController.transition(String(result));
7900
+ return [
7901
+ 3,
7902
+ 8
7903
+ ];
7904
+ case 7:
7905
+ e = _state.sent();
7906
+ flowResultDeferred.reject(e);
7907
+ return [
7908
+ 3,
7909
+ 8
7910
+ ];
7911
+ case 8:
7912
+ expressionEvaluator.reset();
7913
+ return [
7914
+ 2
7915
+ ];
7916
+ }
7917
+ });
7918
+ });
7919
+ return function(flowInstance) {
7920
+ return _ref.apply(this, arguments);
7921
+ };
7922
+ }());
7542
7923
  });
7543
7924
  this.hooks.dataController.call(dataController);
7544
7925
  validationController.setOptions({