<commit_before>import Ember from 'ember';
import BelongsToProxiedRelation from './belongs-to-proxied';
import RelationQueryMixin from './query/relation';
import RelationFirstQueryMixin from './query/relation-first';

const {
  RSVP: { resolve, reject }
} = Ember;

export default class BelongsToLoadedRelation extends BelongsToProxiedRelation {

  constructor() {
    super(...arguments);
    this.load = {
      state: {
        isLoading: false,
        isLoaded: false,
        isError: false,
        error: null
      },
      needsReload: false,
      promise: null,
    };
  }

  get notifyPropertyChangeProxyPropertyNames() {
    return [ 'content', 'promise' ];
  }

  createObjectProxy(owner) {
    let _relation = this;
    return owner.lookup('sofa:belongs-to-loaded').create({ _relation });
  }

  createQuery() {
    return this.relationship.createQuery(this, 'relation-first', Query => {
      return Query.extend(RelationQueryMixin, RelationFirstQueryMixin);
    });
  }

  setLoadState(state, notify=true) {
    for(let key in this.load.state) {
      if(!state.hasOwnProperty(key)) {
        state[key] = this.load.state[key];
      }
    }
    this.load.state = state;
    let value = this.value;
    if(value && notify) {
      value.notifyPropertyChange('state');
    }
  }

  queryNeedsReload() {
    let value = this.value;
    this.load.needsReload = true;
    value.notifyPropertyChange('promise');
  }

  createLoadPromise(notifyInitialStateChange=true) {
    let query = this.getQuery();

    this.setLoadState({
      isLoading: true,
      isError: false,
      error: null
    }, notifyInitialStateChange);

    return query._find().then(internal => {
      this.withPropertyChanges(changed => {
        this.setContent(internal, changed);
      });
      this.setLoadState({
        isLoading: false,
        isLoaded: true,
        isError: false,
        error: false
      });
      return this.getValue();
    }, err => {
      this.setLoadState({
        isLoading: false,
        isError: true,
        error: err
      });
      return reject(err);
    });
  }

  getLoadPromise(notifyInitialStateChange=true) {
    let promise = this.load.promise;
    if(!promise) {
      if(this.content && !this.load.needsReload) {
        return resolve(this.getValue());
      }
      this.load.needsReload = false;
      promise = this.createLoadPromise(notifyInitialStateChange).finally(() => {
        this.load.promise = null;
      });
      this.load.promise = promise;
    }
    return promise;
  }

  getLoadState() {
    this.getLoadPromise(false);
    return this.load.state;
  }

  getModel() {
    this.getLoadPromise();
    return super.getModel(...arguments);
  }

  serialize() {
  }

  deserialize() {
  }

}
<commit_msg>belongs to loaded doesn't retry loads unless load.needed===true<commit_after>import Ember from 'ember';
import BelongsToProxiedRelation from './belongs-to-proxied';
import RelationQueryMixin from './query/relation';
import RelationFirstQueryMixin from './query/relation-first';

const {
  RSVP: { resolve, reject }
} = Ember;

export default class BelongsToLoadedRelation extends BelongsToProxiedRelation {

  constructor() {
    super(...arguments);
    this.load = {
      state: {
        isLoading: false,
        isLoaded: false,
        isError: false,
        error: null
      },
      needed: true,
      promise: null,
    };
  }

  get notifyPropertyChangeProxyPropertyNames() {
    return [ 'content', 'promise' ];
  }

  createObjectProxy(owner) {
    let _relation = this;
    return owner.lookup('sofa:belongs-to-loaded').create({ _relation });
  }

  createQuery() {
    return this.relationship.createQuery(this, 'relation-first', Query => {
      return Query.extend(RelationQueryMixin, RelationFirstQueryMixin);
    });
  }

  setLoadState(state, notify=true) {
    for(let key in this.load.state) {
      if(!state.hasOwnProperty(key)) {
        state[key] = this.load.state[key];
      }
    }
    this.load.state = state;
    let value = this.value;
    if(value && notify) {
      value.notifyPropertyChange('state');
    }
  }

  queryNeedsReload() {
    let value = this.value;
    this.load.needed = true;
    value.beginPropertyChanges();
    value.notifyPropertyChange('promise');
    value.notifyPropertyChange('content');
    value.endPropertyChanges();
  }

  createLoadPromise(notifyInitialStateChange=true) {
    let query = this.getQuery();

    this.setLoadState({
      isLoading: true,
      isError: false,
      error: null
    }, notifyInitialStateChange);

    return query._find().then(internal => {
      this.withPropertyChanges(changed => {
        this.setContent(internal, changed);
      });
      this.setLoadState({
        isLoading: false,
        isLoaded: true,
        isError: false,
        error: false
      });
      return this.getValue();
    }, err => {
      this.setLoadState({
        isLoading: false,
        isError: true,
        error: err
      });
      return reject(err);
    });
  }

  getLoadPromise(notifyInitialStateChange=true) {
    let promise = this.load.promise;
    if(!promise) {
      if(!this.load.needed) {
        return resolve(this.getValue());
      }
      this.load.needed = false;
      promise = this.createLoadPromise(notifyInitialStateChange).finally(() => {
        this.load.promise = null;
      });
      this.load.promise = promise;
    }
    return promise;
  }

  getLoadState() {
    this.getLoadPromise(false);
    return this.load.state;
  }

  getModel() {
    this.getLoadPromise();
    return super.getModel(...arguments);
  }

  serialize() {
  }

  deserialize() {
  }

}

{'fraction_non_alphanumeric': 0.1295575221238938, 'fraction_numerical': 0.0, 'mean_word_length': 2.6458064516129034, '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': '970341', 'n_tokens_mistral': 1761, 'n_tokens_neox': 1724, 'n_words': 317}