var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var FallbackStorage = /** @class */ (function () {
    function FallbackStorage() {
        this.items = {};
    }
    FallbackStorage.prototype.clear = function () {
        this.items = {};
    };
    FallbackStorage.prototype.getItem = function (key) {
        return this.items[key] || null;
    };
    FallbackStorage.prototype.setItem = function (key, data) {
        this.items[key] = data;
    };
    FallbackStorage.prototype.removeItem = function (key) {
        delete this.items[key];
    };
    return FallbackStorage;
}());
/**
 * Per the HTML spec browsers are allowed to throw exceptions for (local/session)Storage so it needs to be wrapped.
 * See: https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage#Exceptions
 */
var StorageWrapper = /** @class */ (function () {
    function StorageWrapper(storage) {
        this.storage = storage;
    }
    StorageWrapper.hasStorage = function (key) {
        try {
            var uid = "anjHasStorage" + +new Date();
            var storage = window[key];
            storage.setItem(uid, uid);
            var test = storage.getItem(uid);
            storage.removeItem(uid);
            return test === uid;
        }
        catch (_ex) {
            return false;
        }
    };
    StorageWrapper.prototype.clear = function () {
        return this.storage.clear();
    };
    StorageWrapper.prototype.getItem = function (key) {
        return JSON.parse(this.storage.getItem(key));
    };
    StorageWrapper.prototype.removeItem = function (key) {
        return this.storage.removeItem(key);
    };
    StorageWrapper.prototype.setItem = function (key, data) {
        return this.storage.setItem(key, JSON.stringify(data));
    };
    return StorageWrapper;
}());
var SessionStorage = /** @class */ (function (_super) {
    __extends(SessionStorage, _super);
    function SessionStorage() {
        var _this = this;
        if (SessionStorage.hasStorage('sessionStorage')) {
            _this = _super.call(this, window.sessionStorage) || this;
        }
        else {
            _this = _super.call(this, new FallbackStorage()) || this;
        }
        return _this;
    }
    return SessionStorage;
}(StorageWrapper));
var LocalStorage = /** @class */ (function (_super) {
    __extends(LocalStorage, _super);
    function LocalStorage() {
        var _this = this;
        if (LocalStorage.hasStorage('localStorage')) {
            _this = _super.call(this, window.localStorage) || this;
        }
        else {
            _this = _super.call(this, new FallbackStorage()) || this;
        }
        return _this;
    }
    return LocalStorage;
}(StorageWrapper));
export { FallbackStorage as F, LocalStorage as L, StorageWrapper as S, SessionStorage as a };
