export class DataProvider {
constructor() {
this.data = {};
}
set(name, data) {
this.data[name] = data;
}
get(name) {
return this.data[name];
}
setRaw(name, data) {
this.set("raw." + name, data);
}
getRaw(name) {
return this.get("raw." + name);
}
/**
* Удалить конкретный ключ из кеша.
* Вызывать после мутаций — например, после переименования устройства.
*/
invalidate(key) {
delete this.data[key];
}
/**
* Удалить все ключи, начинающиеся с prefix.
* Например: invalidatePrefix("raw.devices") очищает весь кеш устройств.
*/
invalidatePrefix(prefix) {
for (const key of Object.keys(this.data)) {
if (key.startsWith(prefix)) {
delete this.data[key];
}
}
}
/**
* Вернуть данные из кеша; если их нет — вызвать fetchFn, закешировать и вернуть.
*
* @param {string} key Ключ в хранилище, например "raw.devices.12"
* @param {function} fetchFn (cb) => void — должна вызвать cb(err, data)
* @param {function} cb (err, data) => void
*
* Пример:
* DataProvider.getOrFetch(
* `raw.devices.${id}`,
* (cb) => sh_api.devices.get(id, (err, resp) => cb(err, resp?.data?.device)),
* (err, device) => { ... }
* );
*/
getOrFetch(key, fetchFn, cb) {
const cached = this.data[key];
if (typeof cached !== "undefined") {
return cb(null, cached);
}
fetchFn((err, data) => {
if (!err && typeof data !== "undefined") {
this.data[key] = data;
}
cb(err, data);
});
}
/**
* Вернуть массив всех закешированных значений, чьи ключи начинаются с prefix.
* Например: getCollection("raw.devices") → [device, device, ...]
*/
getCollection(prefix) {
const result = [];
for (const [key, value] of Object.entries(this.data)) {
if (key.startsWith(prefix)) {
result.push(value);
}
}
return result;
}
}