API Docs for: v3.9.0-beta.1
Show:

File: addon/-private/system/internal-model-map.ts

import { assert } from '@ember/debug';
import InternalModel from './model/internal-model';
import { Dict } from '../types';

/**
 `InternalModelMap` is a custom storage map for internalModels of a given modelName
 used by `IdentityMap`.

 It was extracted from an implicit pojo based "internalModel map" and preserves
 that interface while we work towards a more official API.

 @class InternalModelMap
 @private
 */
export default class InternalModelMap {
  private _idToModel: Dict<string, InternalModel> = Object.create(null);
  private _models: InternalModel[] = [];
  private _metadata: Dict<string, any> | null = null;

  constructor(public modelName: string) {}

  /**
   * @method get
   * @param id {String}
   * @return {InternalModel}
   */
  get(id: string): InternalModel | undefined {
    return this._idToModel[id];
  }

  has(id: string): boolean {
    return !!this._idToModel[id];
  }

  get length(): number {
    return this._models.length;
  }

  set(id: string, internalModel: InternalModel): void {
    assert(
      `You cannot index an internalModel by an empty id'`,
      typeof id === 'string' && id.length > 0
    );
    assert(
      `You cannot set an index for an internalModel to something other than an internalModel`,
      internalModel instanceof InternalModel
    );
    assert(
      `You cannot set an index for an internalModel that is not in the InternalModelMap`,
      this.contains(internalModel)
    );
    assert(
      `You cannot update the id index of an InternalModel once set. Attempted to update ${id}.`,
      !this.has(id) || this.get(id) === internalModel
    );

    this._idToModel[id] = internalModel;
  }

  add(internalModel: InternalModel, id?: string): void {
    assert(
      `You cannot re-add an already present InternalModel to the InternalModelMap.`,
      !this.contains(internalModel)
    );

    if (id) {
      assert(
        `Duplicate InternalModel for ${this.modelName}:${id} detected.`,
        !this.has(id) || this.get(id) === internalModel
      );

      this._idToModel[id] = internalModel;
    }

    this._models.push(internalModel);
  }

  remove(internalModel: InternalModel, id: string): void {
    delete this._idToModel[id];

    let loc = this._models.indexOf(internalModel);

    if (loc !== -1) {
      this._models.splice(loc, 1);
    }
  }

  contains(internalModel: InternalModel): boolean {
    return this._models.indexOf(internalModel) !== -1;
  }

  /**
   An array of all models of this modelName
   @property models
   @type Array
   */
  get models(): InternalModel[] {
    return this._models;
  }

  /**
   * meta information about internalModels
   * @property metadata
   * @type Object
   */
  get metadata(): Dict<string, any> {
    return this._metadata || (this._metadata = Object.create(null));
  }

  /**
   Destroy all models in the internalModelTest and wipe metadata.

   @method clear
   */
  clear(): void {
    let internalModels = this._models;
    this._models = [];

    for (let i = 0; i < internalModels.length; i++) {
      let internalModel = internalModels[i];
      internalModel.unloadRecord();
    }

    this._metadata = null;
  }
}