101 lines
2.7 KiB
JavaScript
101 lines
2.7 KiB
JavaScript
/**
|
||
* Storage - работа с localStorage
|
||
* Пространство имён, обработка ошибок, версионирование схемы
|
||
*/
|
||
|
||
const STORAGE_KEY = 'hr_matcher_v1';
|
||
const SCHEMA_VERSION = 1;
|
||
|
||
const defaultState = {
|
||
schemaVersion: SCHEMA_VERSION,
|
||
vacancyText: '',
|
||
resumeText: '',
|
||
criteria: [],
|
||
matchResults: null,
|
||
questions: [],
|
||
lastUpdated: null
|
||
};
|
||
|
||
function loadState() {
|
||
try {
|
||
const stored = localStorage.getItem(STORAGE_KEY);
|
||
if (!stored) {
|
||
return { ...defaultState };
|
||
}
|
||
|
||
const parsed = JSON.parse(stored);
|
||
|
||
if (!parsed.schemaVersion || parsed.schemaVersion < SCHEMA_VERSION) {
|
||
console.warn('Устаревшая схема данных, миграция...');
|
||
return migrateState(parsed);
|
||
}
|
||
|
||
return { ...defaultState, ...parsed };
|
||
} catch (error) {
|
||
console.error('Ошибка чтения localStorage:', error);
|
||
return { ...defaultState };
|
||
}
|
||
}
|
||
|
||
function saveState(state) {
|
||
try {
|
||
const toSave = {
|
||
...state,
|
||
lastUpdated: new Date().toISOString()
|
||
};
|
||
|
||
localStorage.setItem(STORAGE_KEY, JSON.stringify(toSave));
|
||
return true;
|
||
} catch (error) {
|
||
if (error.name === 'QuotaExceededError') {
|
||
console.error('Превышена квота localStorage. Очистите данные или удалите старые записи.');
|
||
alert('Внимание: Превышен лимит хранилища. Данные не сохранены.');
|
||
} else {
|
||
console.error('Ошибка записи в localStorage:', error);
|
||
}
|
||
return false;
|
||
}
|
||
}
|
||
|
||
function clearState() {
|
||
try {
|
||
localStorage.removeItem(STORAGE_KEY);
|
||
return true;
|
||
} catch (error) {
|
||
console.error('Ошибка очистки localStorage:', error);
|
||
return false;
|
||
}
|
||
}
|
||
|
||
function migrateState(oldState) {
|
||
const migrated = { ...defaultState };
|
||
|
||
if (oldState.vacancyText) migrated.vacancyText = oldState.vacancyText;
|
||
if (oldState.resumeText) migrated.resumeText = oldState.resumeText;
|
||
if (oldState.criteria) migrated.criteria = oldState.criteria;
|
||
if (oldState.matchResults) migrated.matchResults = oldState.matchResults;
|
||
if (oldState.questions) migrated.questions = oldState.questions;
|
||
|
||
migrated.schemaVersion = SCHEMA_VERSION;
|
||
migrated.lastUpdated = new Date().toISOString();
|
||
|
||
saveState(migrated);
|
||
|
||
return migrated;
|
||
}
|
||
|
||
function isStorageAvailable() {
|
||
try {
|
||
const test = '__storage_test__';
|
||
localStorage.setItem(test, test);
|
||
localStorage.removeItem(test);
|
||
return true;
|
||
} catch (error) {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
if (typeof module !== 'undefined' && module.exports) {
|
||
module.exports = { loadState, saveState, clearState, isStorageAvailable, defaultState };
|
||
}
|