synapse-storage
Version:
Набор инструментов для управления состоянием и апи-запросами
132 lines (121 loc) • 5.22 kB
JavaScript
import { SingletonMixin } from "../modules/singleton/mixin.util.js";
import { StorageKey } from "../utils/storage-key.js";
import { getValueByPath, parsePath, setValueByPath } from "./path.utils.js";
import { SyncBaseStorage } from "./sync-base-storage.service.js";
class LocalStorage extends SyncBaseStorage {
static STORAGE_TYPE = 'localStorage';
type = 'localStorage';
constructor(config, eventEmitter, logger){
super(config, eventEmitter, logger);
}
static create(config, eventEmitter, logger) {
return SingletonMixin.handleSingletonCreation(config, this.STORAGE_TYPE, (finalConfig)=>new LocalStorage(finalConfig, eventEmitter, logger), logger);
}
async doInitialize() {
try {
this.logger?.debug(`Initializing LocalStorage "${this.name}"`);
this.initializeMiddlewares();
this.initializeWithMiddlewares();
this.logger?.debug(`LocalStorage "${this.name}" initialized successfully`);
return this;
} catch (error) {
this.logger?.error('Error initializing LocalStorage', {
error
});
throw error;
}
}
doGet(key) {
const storageData = localStorage.getItem(this.name);
if (!storageData) return undefined;
const state = JSON.parse(storageData);
if (key instanceof StorageKey && key.isUnparseable()) {
return state[key.valueOf()];
}
return getValueByPath(state, key);
}
doSet(key, value) {
const storageData = localStorage.getItem(this.name);
const state = storageData ? JSON.parse(storageData) : {};
if (key instanceof StorageKey && key.isUnparseable()) {
state[key.valueOf()] = value;
localStorage.setItem(this.name, JSON.stringify(state));
return;
}
const newState = setValueByPath({
...state
}, key, value);
localStorage.setItem(this.name, JSON.stringify(newState));
}
doRemove(key) {
const storageData = localStorage.getItem(this.name);
if (!storageData) return false;
const state = JSON.parse(storageData);
if (key instanceof StorageKey && key.isUnparseable()) {
const rawKey = key.valueOf();
if (!(rawKey in state)) return false;
delete state[rawKey];
localStorage.setItem(this.name, JSON.stringify(state));
return true;
}
const pathParts = parsePath(key);
const parentPath = pathParts.slice(0, -1).join('.');
const lastKey = pathParts[pathParts.length - 1];
const parent = parentPath ? getValueByPath(state, parentPath) : state;
if (!parent || !(lastKey in parent)) return false;
delete parent[lastKey];
localStorage.setItem(this.name, JSON.stringify(state));
return true;
}
doUpdate(updates) {
const storageData = localStorage.getItem(this.name);
let state = storageData ? JSON.parse(storageData) : {};
for (const { key, value } of updates){
if (key instanceof StorageKey && key.isUnparseable()) {
state[key.valueOf()] = value;
} else {
// setValueByPath иммутабелен → переприсваиваем результат.
state = setValueByPath(state, key, value);
}
}
localStorage.setItem(this.name, JSON.stringify(state));
}
doClear() {
localStorage.removeItem(this.name);
}
doKeys() {
const storageData = localStorage.getItem(this.name);
if (!storageData) return [];
const state = JSON.parse(storageData);
return Object.keys(state);
}
doHas(key) {
const value = this.doGet(key);
return value !== undefined;
}
/** Персистентное хранилище: по умолчанию НЕ чистим данные на destroy (симметрично IndexedDB). */ get clearOnDestroyDefault() {
return false;
}
// ─── Persisted schema version (persist-migration) ───────────────────────────
/** Версия схемы хранится отдельным sidecar-ключом, не засоряя сам state. */ get versionStorageKey() {
return `${this.name}::__synapse_version__`;
}
readPersistedVersion() {
const raw = localStorage.getItem(this.versionStorageKey);
if (raw == null) return undefined;
const parsed = Number(raw);
return Number.isFinite(parsed) ? parsed : undefined;
}
writePersistedVersion(version) {
localStorage.setItem(this.versionStorageKey, String(version));
}
clearPersistedVersion() {
localStorage.removeItem(this.versionStorageKey);
}
async doDestroy() {
// Персистентное хранилище: данные не стираются на destroy.
// Очистка управляется флагом config.clearOnDestroy в performCleanup.
}
}
export { LocalStorage };
//# sourceMappingURL=local-storage.service.js.map