/* HR Candidate Matcher — Storage Layer */ /* global window */ (function () { 'use strict'; var APP = window.HRMatcher = window.HRMatcher || {}; var NAMESPACE = 'hr_matcher'; var SCHEMA_VERSION = 1; var STORAGE_KEY = NAMESPACE + '_v' + SCHEMA_VERSION; var storageAvailable = false; var memoryFallback = {}; function testStorage() { try { var test = '__storage_test__'; localStorage.setItem(test, test); localStorage.removeItem(test); return true; } catch (e) { return false; } } storageAvailable = testStorage(); APP.storage = { isAvailable: function () { return storageAvailable; }, save: function (data) { var payload = { version: SCHEMA_VERSION, timestamp: Date.now(), data: data }; if (storageAvailable) { try { localStorage.setItem(STORAGE_KEY, JSON.stringify(payload)); return true; } catch (e) { if (e.name === 'QuotaExceededError' || e.code === 22) { APP.ui && APP.ui.showToast && APP.ui.showToast('Хранилище переполнено. Изменения не сохраняются.', 'error'); } memoryFallback = payload; return false; } } else { memoryFallback = payload; return false; } }, load: function () { if (storageAvailable) { try { var raw = localStorage.getItem(STORAGE_KEY); if (!raw) return null; var parsed = JSON.parse(raw); if (parsed && parsed.version === SCHEMA_VERSION && parsed.data) { return parsed.data; } return null; } catch (e) { return null; } } return memoryFallback && memoryFallback.data ? memoryFallback.data : null; }, clear: function () { if (storageAvailable) { try { localStorage.removeItem(STORAGE_KEY); } catch (e) { /* ignore */ } } memoryFallback = {}; }, savePartial: function (key, value) { var current = this.load() || {}; current[key] = value; return this.save(current); }, removePartial: function (key) { var current = this.load() || {}; delete current[key]; return this.save(current); } }; })();