<commit_before>import {ViewStrategy, UseView} from './view-strategy';
import {ResourceCoordinator} from './resource-coordinator';
import {ViewEngine} from './view-engine';
import {CustomElement} from './custom-element';

export class CompositionEngine {
  static inject(){ return [ResourceCoordinator, ViewEngine]; }
  constructor(resourceCoordinator, viewEngine){
    this.resourceCoordinator = resourceCoordinator;
    this.viewEngine = viewEngine;
  }

  bindAndSwap(viewSlot, next, current){
    next.bind(next.executionContext);
    viewSlot.swap(next.view);

    if(current){
      current.unbind();
    }

    return next;
  }

  activateViewModel(viewModel, model){
    if(typeof viewModel.activate === 'function') {
      return viewModel.activate(model) || Promise.resolve();
    }else{
      return Promise.resolve();
    }
  }

  createBehavior(instruction, container, viewModelInfo){
    return this.activateViewModel(instruction.viewModel, instruction.model).then(() => {
      var doneLoading;

      if('getViewStrategy' in instruction.viewModel && !instruction.view){
        instruction.view = ViewStrategy.normalize(instruction.viewModel.getViewStrategy());
      }

      if(viewModelInfo){
        doneLoading = viewModelInfo.type.load(container, viewModelInfo.value, instruction.view);
      }else{
        doneLoading = new CustomElement().load(container, instruction.viewModel.constructor, instruction.view);
      }

      return doneLoading.then(behaviorType => {
        var behavior = behaviorType.create(container, {executionContext:instruction.viewModel, suppressBind:true});
        return this.bindAndSwap(instruction.viewSlot, behavior, instruction.currentBehavior);
      });
    });
  }

  compose(instruction){
    var childContainer;
    
    instruction.view = ViewStrategy.normalize(instruction.view);

    if(typeof instruction.viewModel === 'string'){
      instruction.viewModel = instruction.viewResources 
        ? instruction.viewResources.relativeToView(instruction.viewModel)
        : instruction.viewModel;
      
      return this.resourceCoordinator.loadViewModelInfo(instruction.viewModel).then(viewModelInfo => {
        childContainer = instruction.container.createChild();
        childContainer.autoRegister(viewModelInfo.value);
        instruction.viewModel = childContainer.get(viewModelInfo.value);
        return this.createBehavior(instruction, childContainer, viewModelInfo);
      });
    }else{
      if(instruction.viewModel){
        return this.createBehavior(instruction, instruction.container.createChild());
      } else if (instruction.view){
        return instruction.view.loadViewFactory(this.viewEngine).then(viewFactory => {
          childContainer = instruction.container.createChild();
          result = viewFactory.create(childContainer, instruction.executionContext);
          instruction.viewSlot.swap(result);
        });
      }
    }
  }
}<commit_msg>fix(composition-engine): more consistent api<commit_after>import {ViewStrategy, UseView} from './view-strategy';
import {ResourceCoordinator} from './resource-coordinator';
import {ViewEngine} from './view-engine';
import {CustomElement} from './custom-element';

export class CompositionEngine {
  static inject(){ return [ResourceCoordinator, ViewEngine]; }
  constructor(resourceCoordinator, viewEngine){
    this.resourceCoordinator = resourceCoordinator;
    this.viewEngine = viewEngine;
  }

  activate(instruction){
    if(instruction.skipActivation || typeof instruction.viewModel.activate !== 'function'){
      return Promise.resolve(); 
    }

    return instruction.viewModel.activate(instruction.model) || Promise.resolve();
  }

  createBehaviorAndSwap(instruction){
    return this.createBehavior(instruction).then(behavior => {
      instruction.viewSlot.swap(behavior.view);

      if(instruction.currentBehavior){
        instruction.currentBehavior.unbind();
      }

      return behavior;
    });
  }

  createBehavior(instruction){
    var childContainer = instruction.childContainer,
        viewModelInfo = instruction.viewModelInfo,
        viewModel = instruction.viewModel;

    return this.activate(instruction).then(() => {
      var doneLoading;

      if('getViewStrategy' in viewModel && !instruction.view){
        instruction.view = ViewStrategy.normalize(viewModel.getViewStrategy());
      }

      if(viewModelInfo){
        doneLoading = viewModelInfo.type.load(childContainer, viewModelInfo.value, instruction.view);
      }else{
        doneLoading = new CustomElement().load(childContainer, viewModel.constructor, instruction.view);
      }

      return doneLoading.then(behaviorType => {
        return behaviorType.create(childContainer, {executionContext:viewModel});
      });
    });
  }

  createViewModel(instruction){
    var childContainer = instruction.childContainer || instruction.container.createChild();

    instruction.viewModel = instruction.viewResources 
        ? instruction.viewResources.relativeToView(instruction.viewModel)
        : instruction.viewModel;
      
    return this.resourceCoordinator.loadViewModelInfo(instruction.viewModel).then(viewModelInfo => {
      childContainer.autoRegister(viewModelInfo.value);
      instruction.viewModel = childContainer.get(viewModelInfo.value);
      instruction.viewModelInfo = viewModelInfo;
      return instruction;
    });
  }

  compose(instruction){
    instruction.childContainer = instruction.childContainer || instruction.container.createChild();
    instruction.view = ViewStrategy.normalize(instruction.view);

    if(instruction.viewModel){
      if(typeof instruction.viewModel === 'string'){
        return this.createViewModel(instruction).then(instruction => {
          return this.createBehaviorAndSwap(instruction);
        });
      }else{
        return this.createBehaviorAndSwap(instruction);
      }
    }else if(instruction.view){
      return instruction.view.loadViewFactory(this.viewEngine).then(viewFactory => {
        result = viewFactory.create(childContainer, instruction.executionContext);
        instruction.viewSlot.swap(result);
        return result;
      });
    }else if(instruction.viewSlot){
      instruction.viewSlot.removeAll();
      return Promise.resolve(null);
    }
  }
}
{'fraction_non_alphanumeric': 0.11245619624084104, 'fraction_numerical': 0.0, 'mean_word_length': 3.8151840490797544, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2728500', 'n_tokens_mistral': 1649, 'n_tokens_neox': 1569, 'n_words': 262}