"use strict";

exports.__esModule = true;
exports.default = exports.TransientsShadow = undefined;

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _akutils = require("akutils");

var _es6Symbol = require("es6-symbol");

var _es6Symbol2 = _interopRequireDefault(_es6Symbol);

var _ObjectProperty2 = require("./ObjectProperty");

var _ObjectProperty3 = _interopRequireDefault(_ObjectProperty2);

var _Shadow2 = require("./Shadow");

var _Shadow3 = _interopRequireDefault(_Shadow2);

var _StateType = require("./StateType");

var _StateType2 = _interopRequireDefault(_StateType);

var _TransientProperty = require("./TransientProperty");

var _TransientProperty2 = _interopRequireDefault(_TransientProperty);

var _debug = require("./debug");

var _debug2 = _interopRequireDefault(_debug);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var debug = (0, _debug2.default)(_debug.TransientKey);

/**
	The shadow api for the {@link Store#transients} property. This api implements a superset of the
	[Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) class.
*/

var TransientsShadow = exports.TransientsShadow = function (_Shadow) {
	_inherits(TransientsShadow, _Shadow);

	function TransientsShadow() {
		_classCallCheck(this, TransientsShadow);

		return _possibleConstructorReturn(this, Object.getPrototypeOf(TransientsShadow).apply(this, arguments));
	}

	_createClass(TransientsShadow, [{
		key: "clear",


		/**
  	Removes all transient objects.
  */
		value: function clear() {
			this.__().clear();
		}

		/**
  	Removes the speecified transient object from {@link Store#transients}.
  		@param id - the transient key
  */

	}, {
		key: "delete",
		value: function _delete(id) {
			this.$$()._keyed.removeProperty(id);
		}

		/**
  	Gets an [Iterator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators)
  	object that contains the `[id, {@link TransientShadow}]` pairs for each transient property in the
  	{@link Store#transients} property.
  */

	}, {
		key: "entries",
		value: function entries() {
			var _this2 = this;

			return (0, _akutils.iterateOver)(this.__().keys(), function (key) {
				return [key, _this2[key]];
			});
		}
	}, {
		key: "get",
		value: function get(id) {
			if (this.__().has(id)) {
				return this[id].$$();
			} else {
				return this.$$().getFromCache(id);
			}
		}

		/**
  	Gets if the {@link Store#transients} object contains a transient object.
  */

	}, {
		key: "has",
		value: function has(id) {
			return this.__().has(id) || this.$$().isCached(id);
		}

		/**
  	Gets an [Iterator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators)
  	object that contains the transient keys.
  */

	}, {
		key: "keys",
		value: function keys() {
			return (0, _akutils.iteratorFor)(this.__().keys());
		}

		/**
  	Adds or updates a {@link TransientProperty} with a specified id. The returned {@link TransientProperty#link}
  	method must be called immediately following this method invocation or the property may be swept from the
  	transient list after the next store update.
  		@param id - the transient key
  	@param {Property} property - a `Property` instance to track in the transients property.
  		@return the {@link TransientProperty} containing the `property` instance passed into the
  		method.
  */

	}, {
		key: "set",
		value: function set(id, property) {
			(0, _akutils.assert)(function (a) {
				return a.is(id, "id must be specifeid for setting a transient property");
			});

			var trans = new _TransientProperty2.default(id, property);

			this.$$()._keyed.addProperty(id, trans);
			this.$$().addToCache(id, trans);

			return trans;
		}

		/**
  	Invoked by {@link Store#_exec} to remove unlocked transient objects.
  */

	}, {
		key: "sweep",
		value: function sweep() {
			var property = this.$$();
			var keys = property._keyed.keysArray();

			for (var i = 0, t; t = this[keys[i]]; i++) {
				if (!t.isLocked()) {
					this.delete(keys[i]);
				}
			}
		}

		/**
  	Gets an [Iterator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators)
  	object that contains the {@link TransientShadow} instances.
  */

	}, {
		key: "values",
		value: function values() {
			var _this3 = this;

			return (0, _akutils.iterateOver)(this.__().keys(), function (key) {
				return _this3[key];
			});
		}
	}, {
		key: _es6Symbol2.default.iterator,
		value: function value() {
			return this.entries();
		}
	}, {
		key: "size",

		/*
  	Gets the number of transient objects.
  */
		get: function get() {
			return this.__().size();
		}
	}]);

	return TransientsShadow;
}(_Shadow3.default);

/**
	The property representing {@link Store#transients}

	@see {@link TransientsShadow}
*/


var TransientsProperty = function (_ObjectProperty) {
	_inherits(TransientsProperty, _ObjectProperty);

	function TransientsProperty(type) {
		_classCallCheck(this, TransientsProperty);

		var _this4 = _possibleConstructorReturn(this, Object.getPrototypeOf(TransientsProperty).call(this, type));

		_this4.setShadowClass(TransientsShadow);
		_this4.cache = {};
		return _this4;
	}

	_createClass(TransientsProperty, [{
		key: "propertyDidUpdate",
		value: function propertyDidUpdate() {
			this.cache = {};
		}
	}, {
		key: "addToCache",
		value: function addToCache(id, transProp) {
			this.cache[id] = transProp;
		}
	}, {
		key: "getFromCache",
		value: function getFromCache(id) {
			return this.cache[id];
		}
	}, {
		key: "isCached",
		value: function isCached(id) {
			return !!this.cache[id];
		}
	}]);

	return TransientsProperty;
}(_ObjectProperty3.default);

exports.default = TransientsProperty;


_StateType2.default.defineType(TransientsProperty, function (spec) {
	spec.initialState({}).autoshadowOff.readonly.typeName("TransientsProperty");
});