use of com.vaadin.flow.internal.nodefeature.ReturnChannelRegistration in project flow by vaadin.
the class UidlWriter method encodeExecuteJavaScript.
private static JsonArray encodeExecuteJavaScript(PendingJavaScriptInvocation invocation) {
List<Object> parametersList = invocation.getInvocation().getParameters();
Stream<Object> parameters = parametersList.stream();
String expression = invocation.getInvocation().getExpression();
if (invocation.isSubscribed()) {
StateNode owner = invocation.getOwner();
List<ReturnChannelRegistration> channels = new ArrayList<>();
ReturnChannelRegistration successChannel = createReturnValueChannel(owner, channels, invocation::complete);
ReturnChannelRegistration errorChannel = createReturnValueChannel(owner, channels, invocation::completeExceptionally);
// Inject both channels as new parameters
parameters = Stream.concat(parameters, Stream.of(successChannel, errorChannel));
int successIndex = parametersList.size();
int errorIndex = successIndex + 1;
/*
* Run the original expression wrapped in a function to capture any
* return statement. Pass the return value through Promise.resolve
* which resolves regular values immediately and waits for thenable
* values. Call either of the handlers once the promise completes.
* If the expression throws synchronously, run the error handler.
*/
// @formatter:off
expression = "try{" + "Promise.resolve((function(){" + expression + "})()).then($" + successIndex + ",function(error){$" + errorIndex + "(''+error)})" + "}catch(error){" + "$" + errorIndex + "(''+error)" + "}";
// @formatter:on
}
// [argument1, argument2, ..., script]
return Stream.concat(parameters.map(JsonCodec::encodeWithTypeInfo), Stream.of(Json.create(expression))).collect(JsonUtils.asArray());
}
use of com.vaadin.flow.internal.nodefeature.ReturnChannelRegistration in project flow by vaadin.
the class ReturnChannelHandlerTest method happyPath_everythingWorks.
@Test
public void happyPath_everythingWorks() {
ReturnChannelRegistration registration = registerUiChannel();
handleMessage(registration);
Assert.assertSame("Handler should have been invoked with the given arguments.", args, observedArguments.get());
}
use of com.vaadin.flow.internal.nodefeature.ReturnChannelRegistration in project flow by vaadin.
the class ReturnChannelHandlerTest method disabledElement_registrationAlwaysAllowed_invocationProcessed.
@Test
public void disabledElement_registrationAlwaysAllowed_invocationProcessed() {
ReturnChannelRegistration registration = registerUiChannel();
registration.setDisabledUpdateMode(DisabledUpdateMode.ALWAYS);
ui.setEnabled(false);
handleMessage(registration);
Assert.assertNotNull("Channel handler should be called", observedArguments.get());
}
use of com.vaadin.flow.internal.nodefeature.ReturnChannelRegistration in project flow by vaadin.
the class ReturnChannelHandler method handleNode.
@Override
protected Optional<Runnable> handleNode(StateNode node, JsonObject invocationJson) {
int channelId = (int) invocationJson.getNumber(JsonConstants.RPC_CHANNEL);
JsonArray arguments = invocationJson.getArray(JsonConstants.RPC_CHANNEL_ARGUMENTS);
if (!node.hasFeature(ReturnChannelMap.class)) {
getLogger().warn("Node has no return channels: {}", invocationJson);
return Optional.empty();
}
ReturnChannelRegistration channel = node.getFeatureIfInitialized(ReturnChannelMap.class).map(map -> map.get(channelId)).orElse(null);
if (channel == null) {
getLogger().warn("Return channel not found: {}", invocationJson);
return Optional.empty();
}
if (!node.isEnabled() && channel.getDisabledUpdateMode() != DisabledUpdateMode.ALWAYS) {
getLogger().warn("Ignoring update for disabled return channel: {}", invocationJson);
return Optional.empty();
}
channel.invoke(arguments);
return Optional.empty();
}
use of com.vaadin.flow.internal.nodefeature.ReturnChannelRegistration in project flow by vaadin.
the class UidlWriter method createReturnValueChannel.
private static ReturnChannelRegistration createReturnValueChannel(StateNode owner, List<ReturnChannelRegistration> registrations, SerializableConsumer<JsonValue> action) {
ReturnChannelRegistration channel = owner.getFeature(ReturnChannelMap.class).registerChannel(arguments -> {
registrations.forEach(ReturnChannelRegistration::remove);
action.accept(arguments.get(0));
});
registrations.add(channel);
return channel;
}
Aggregations