docs: implement Antigravity global rules
This commit is contained in:
@@ -1,209 +1,209 @@
|
||||
/**
|
||||
* CacheManager - Gerenciador central do sistema de cache
|
||||
* Coordena IndexedDB, sincronização e acesso aos dados
|
||||
*/
|
||||
|
||||
class CacheManager {
|
||||
constructor(config = {}) {
|
||||
this.dbName = config.dbName || 'AcoCalcProDB';
|
||||
this.version = config.version || 1;
|
||||
this.db = null;
|
||||
this.config = {
|
||||
debug: config.debug || false,
|
||||
autoSync: config.autoSync || false,
|
||||
cacheExpiry: config.cacheExpiry || (7 * 24 * 60 * 60 * 1000), // 7 dias
|
||||
...config
|
||||
};
|
||||
|
||||
this.stores = [
|
||||
'cantoneiras',
|
||||
'barras',
|
||||
'barras_chatas',
|
||||
'barras_roscadas',
|
||||
'tubos_circulares',
|
||||
'tubos_rhs',
|
||||
'chapas',
|
||||
'perfis_i',
|
||||
'perfis_w',
|
||||
'perfis_hp',
|
||||
'_metadata',
|
||||
'_config'
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Inicializa o IndexedDB
|
||||
*/
|
||||
async init() {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!window.indexedDB) {
|
||||
console.warn('⚠️ IndexedDB não disponível - usando fallback para CSV');
|
||||
resolve(false);
|
||||
return;
|
||||
}
|
||||
|
||||
const request = indexedDB.open(this.dbName, this.version);
|
||||
|
||||
request.onerror = () => {
|
||||
console.error('❌ Erro ao abrir IndexedDB:', request.error);
|
||||
reject(request.error);
|
||||
};
|
||||
|
||||
request.onsuccess = () => {
|
||||
this.db = request.result;
|
||||
if (this.config.debug) {
|
||||
console.log('✅ IndexedDB inicializado:', this.dbName);
|
||||
}
|
||||
resolve(true);
|
||||
};
|
||||
|
||||
request.onupgradeneeded = (event) => {
|
||||
const db = event.target.result;
|
||||
|
||||
// Criar stores para cada tipo de perfil
|
||||
this.stores.forEach(storeName => {
|
||||
if (!db.objectStoreNames.contains(storeName)) {
|
||||
const store = db.createObjectStore(storeName, { keyPath: 'id' });
|
||||
|
||||
// Criar índices para busca rápida
|
||||
if (storeName !== '_metadata' && storeName !== '_config') {
|
||||
store.createIndex('nome', 'nome', { unique: false });
|
||||
store.createIndex('tipo', 'tipo', { unique: false });
|
||||
}
|
||||
|
||||
if (this.config.debug) {
|
||||
console.log(`✅ Store criada: ${storeName}`);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifica saúde do cache
|
||||
*/
|
||||
async checkHealth() {
|
||||
if (!this.db) {
|
||||
return {
|
||||
healthy: false,
|
||||
error: 'Database not initialized'
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
const stats = {};
|
||||
|
||||
for (const storeName of this.stores) {
|
||||
if (storeName.startsWith('_')) continue;
|
||||
|
||||
const count = await this.count(storeName);
|
||||
const metadata = await this.getMetadata(storeName);
|
||||
|
||||
stats[storeName] = {
|
||||
count,
|
||||
lastSync: metadata?.lastSync || null,
|
||||
size: metadata?.size || 0
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
healthy: true,
|
||||
stats,
|
||||
totalSize: Object.values(stats).reduce((sum, s) => sum + s.size, 0)
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
healthy: false,
|
||||
error: error.message
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Limpa todo o cache
|
||||
*/
|
||||
async clearAll() {
|
||||
if (!this.db) {
|
||||
throw new Error('Database not initialized');
|
||||
}
|
||||
|
||||
const promises = this.stores
|
||||
.filter(s => !s.startsWith('_'))
|
||||
.map(storeName => this.clear(storeName));
|
||||
|
||||
await Promise.all(promises);
|
||||
|
||||
if (this.config.debug) {
|
||||
console.log('✅ Todo o cache foi limpo');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Conta registros em uma store
|
||||
*/
|
||||
async count(storeName) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const transaction = this.db.transaction([storeName], 'readonly');
|
||||
const store = transaction.objectStore(storeName);
|
||||
const request = store.count();
|
||||
|
||||
request.onsuccess = () => resolve(request.result);
|
||||
request.onerror = () => reject(request.error);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Limpa uma store específica
|
||||
*/
|
||||
async clear(storeName) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const transaction = this.db.transaction([storeName], 'readwrite');
|
||||
const store = transaction.objectStore(storeName);
|
||||
const request = store.clear();
|
||||
|
||||
request.onsuccess = () => resolve();
|
||||
request.onerror = () => reject(request.error);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Busca metadados de um tipo
|
||||
*/
|
||||
async getMetadata(tipo) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const transaction = this.db.transaction(['_metadata'], 'readonly');
|
||||
const store = transaction.objectStore('_metadata');
|
||||
const request = store.get(tipo);
|
||||
|
||||
request.onsuccess = () => resolve(request.result || null);
|
||||
request.onerror = () => reject(request.error);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Salva metadados de um tipo
|
||||
*/
|
||||
async setMetadata(tipo, metadata) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const transaction = this.db.transaction(['_metadata'], 'readwrite');
|
||||
const store = transaction.objectStore('_metadata');
|
||||
const request = store.put({ tipo, ...metadata });
|
||||
|
||||
request.onsuccess = () => resolve();
|
||||
request.onerror = () => reject(request.error);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Retorna estatísticas de uso
|
||||
*/
|
||||
getStats() {
|
||||
return this.checkHealth();
|
||||
}
|
||||
}
|
||||
|
||||
// Exportar para uso global
|
||||
window.CacheManager = CacheManager;
|
||||
|
||||
console.log('✅ CacheManager carregado');
|
||||
/**
|
||||
* CacheManager - Gerenciador central do sistema de cache
|
||||
* Coordena IndexedDB, sincronização e acesso aos dados
|
||||
*/
|
||||
|
||||
class CacheManager {
|
||||
constructor(config = {}) {
|
||||
this.dbName = config.dbName || 'AcoCalcProDB';
|
||||
this.version = config.version || 1;
|
||||
this.db = null;
|
||||
this.config = {
|
||||
debug: config.debug || false,
|
||||
autoSync: config.autoSync || false,
|
||||
cacheExpiry: config.cacheExpiry || (7 * 24 * 60 * 60 * 1000), // 7 dias
|
||||
...config
|
||||
};
|
||||
|
||||
this.stores = [
|
||||
'cantoneiras',
|
||||
'barras',
|
||||
'barras_chatas',
|
||||
'barras_roscadas',
|
||||
'tubos_circulares',
|
||||
'tubos_rhs',
|
||||
'chapas',
|
||||
'perfis_i',
|
||||
'perfis_w',
|
||||
'perfis_hp',
|
||||
'_metadata',
|
||||
'_config'
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Inicializa o IndexedDB
|
||||
*/
|
||||
async init() {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!window.indexedDB) {
|
||||
console.warn('⚠️ IndexedDB não disponível - usando fallback para CSV');
|
||||
resolve(false);
|
||||
return;
|
||||
}
|
||||
|
||||
const request = indexedDB.open(this.dbName, this.version);
|
||||
|
||||
request.onerror = () => {
|
||||
console.error('❌ Erro ao abrir IndexedDB:', request.error);
|
||||
reject(request.error);
|
||||
};
|
||||
|
||||
request.onsuccess = () => {
|
||||
this.db = request.result;
|
||||
if (this.config.debug) {
|
||||
console.log('✅ IndexedDB inicializado:', this.dbName);
|
||||
}
|
||||
resolve(true);
|
||||
};
|
||||
|
||||
request.onupgradeneeded = (event) => {
|
||||
const db = event.target.result;
|
||||
|
||||
// Criar stores para cada tipo de perfil
|
||||
this.stores.forEach(storeName => {
|
||||
if (!db.objectStoreNames.contains(storeName)) {
|
||||
const store = db.createObjectStore(storeName, { keyPath: 'id' });
|
||||
|
||||
// Criar índices para busca rápida
|
||||
if (storeName !== '_metadata' && storeName !== '_config') {
|
||||
store.createIndex('nome', 'nome', { unique: false });
|
||||
store.createIndex('tipo', 'tipo', { unique: false });
|
||||
}
|
||||
|
||||
if (this.config.debug) {
|
||||
console.log(`✅ Store criada: ${storeName}`);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifica saúde do cache
|
||||
*/
|
||||
async checkHealth() {
|
||||
if (!this.db) {
|
||||
return {
|
||||
healthy: false,
|
||||
error: 'Database not initialized'
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
const stats = {};
|
||||
|
||||
for (const storeName of this.stores) {
|
||||
if (storeName.startsWith('_')) continue;
|
||||
|
||||
const count = await this.count(storeName);
|
||||
const metadata = await this.getMetadata(storeName);
|
||||
|
||||
stats[storeName] = {
|
||||
count,
|
||||
lastSync: metadata?.lastSync || null,
|
||||
size: metadata?.size || 0
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
healthy: true,
|
||||
stats,
|
||||
totalSize: Object.values(stats).reduce((sum, s) => sum + s.size, 0)
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
healthy: false,
|
||||
error: error.message
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Limpa todo o cache
|
||||
*/
|
||||
async clearAll() {
|
||||
if (!this.db) {
|
||||
throw new Error('Database not initialized');
|
||||
}
|
||||
|
||||
const promises = this.stores
|
||||
.filter(s => !s.startsWith('_'))
|
||||
.map(storeName => this.clear(storeName));
|
||||
|
||||
await Promise.all(promises);
|
||||
|
||||
if (this.config.debug) {
|
||||
console.log('✅ Todo o cache foi limpo');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Conta registros em uma store
|
||||
*/
|
||||
async count(storeName) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const transaction = this.db.transaction([storeName], 'readonly');
|
||||
const store = transaction.objectStore(storeName);
|
||||
const request = store.count();
|
||||
|
||||
request.onsuccess = () => resolve(request.result);
|
||||
request.onerror = () => reject(request.error);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Limpa uma store específica
|
||||
*/
|
||||
async clear(storeName) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const transaction = this.db.transaction([storeName], 'readwrite');
|
||||
const store = transaction.objectStore(storeName);
|
||||
const request = store.clear();
|
||||
|
||||
request.onsuccess = () => resolve();
|
||||
request.onerror = () => reject(request.error);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Busca metadados de um tipo
|
||||
*/
|
||||
async getMetadata(tipo) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const transaction = this.db.transaction(['_metadata'], 'readonly');
|
||||
const store = transaction.objectStore('_metadata');
|
||||
const request = store.get(tipo);
|
||||
|
||||
request.onsuccess = () => resolve(request.result || null);
|
||||
request.onerror = () => reject(request.error);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Salva metadados de um tipo
|
||||
*/
|
||||
async setMetadata(tipo, metadata) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const transaction = this.db.transaction(['_metadata'], 'readwrite');
|
||||
const store = transaction.objectStore('_metadata');
|
||||
const request = store.put({ tipo, ...metadata });
|
||||
|
||||
request.onsuccess = () => resolve();
|
||||
request.onerror = () => reject(request.error);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Retorna estatísticas de uso
|
||||
*/
|
||||
getStats() {
|
||||
return this.checkHealth();
|
||||
}
|
||||
}
|
||||
|
||||
// Exportar para uso global
|
||||
window.CacheManager = CacheManager;
|
||||
|
||||
console.log('✅ CacheManager carregado');
|
||||
|
||||
@@ -1,91 +1,91 @@
|
||||
/**
|
||||
* Application State Management
|
||||
* Central state for the entire application
|
||||
*/
|
||||
|
||||
// Main application state
|
||||
export const appState = {
|
||||
history: [],
|
||||
favorites: [],
|
||||
budgetItems: [],
|
||||
currentSection: 'cev',
|
||||
currentTheme: 'dark',
|
||||
expertMode: false,
|
||||
currentSidebarTab: 0
|
||||
};
|
||||
|
||||
// User preferences (persisted to localStorage)
|
||||
export const userPreferences = {
|
||||
theme: 'dark',
|
||||
colorScheme: 'default', // default, blue, green, purple, orange
|
||||
fontSize: 'medium', // small, medium, large, xlarge
|
||||
fontFamily: 'default' // default, modern, classic, mono
|
||||
};
|
||||
|
||||
// Admin configuration
|
||||
export const adminConfig = {
|
||||
appName: 'SteelBase',
|
||||
appSubtitle: 'Plataforma Técnica com Base de Dados de Materiais Brasileiros',
|
||||
footerText: '© 2025 SteelBase v7.5 PROFESSIONAL EDITION - Plataforma Técnica com Base de Dados de Materiais Brasileiros',
|
||||
themeDefault: 'escuro',
|
||||
modeDefault: 'simples',
|
||||
toolsVisibility: {
|
||||
'cev': true,
|
||||
'seletor': true,
|
||||
'equivalencias': false,
|
||||
'comparativo': false,
|
||||
'parafusos': true,
|
||||
'layout': true,
|
||||
'parafuso-vs-solda': false,
|
||||
'preaquecimento': true,
|
||||
'dureza': true,
|
||||
'charpy': true,
|
||||
'certificado': false,
|
||||
'ultrassom': false,
|
||||
'area-pintura': true,
|
||||
'consumo-tinta': true,
|
||||
'galvanizacao': false,
|
||||
'custo-pintura': true,
|
||||
'secagem': false,
|
||||
'inspecao-pintura': false,
|
||||
'orcamento': true,
|
||||
'peso-rigging': false,
|
||||
'referencia': false
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Update app state
|
||||
* @param {string} key - State key
|
||||
* @param {any} value - New value
|
||||
*/
|
||||
export function updateState(key, value) {
|
||||
appState[key] = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get state value
|
||||
* @param {string} key - State key
|
||||
* @returns {any} State value
|
||||
*/
|
||||
export function getState(key) {
|
||||
return appState[key];
|
||||
}
|
||||
|
||||
/**
|
||||
* Update user preferences
|
||||
* @param {string} key - Preference key
|
||||
* @param {any} value - New value
|
||||
*/
|
||||
export function updatePreference(key, value) {
|
||||
userPreferences[key] = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get preference value
|
||||
* @param {string} key - Preference key
|
||||
* @returns {any} Preference value
|
||||
*/
|
||||
export function getPreference(key) {
|
||||
return userPreferences[key];
|
||||
}
|
||||
/**
|
||||
* Application State Management
|
||||
* Central state for the entire application
|
||||
*/
|
||||
|
||||
// Main application state
|
||||
export const appState = {
|
||||
history: [],
|
||||
favorites: [],
|
||||
budgetItems: [],
|
||||
currentSection: 'cev',
|
||||
currentTheme: 'dark',
|
||||
expertMode: false,
|
||||
currentSidebarTab: 0
|
||||
};
|
||||
|
||||
// User preferences (persisted to localStorage)
|
||||
export const userPreferences = {
|
||||
theme: 'dark',
|
||||
colorScheme: 'default', // default, blue, green, purple, orange
|
||||
fontSize: 'medium', // small, medium, large, xlarge
|
||||
fontFamily: 'default' // default, modern, classic, mono
|
||||
};
|
||||
|
||||
// Admin configuration
|
||||
export const adminConfig = {
|
||||
appName: 'SteelBase',
|
||||
appSubtitle: 'Plataforma Técnica com Base de Dados de Materiais Brasileiros',
|
||||
footerText: '© 2025 SteelBase v7.5 PROFESSIONAL EDITION - Plataforma Técnica com Base de Dados de Materiais Brasileiros',
|
||||
themeDefault: 'escuro',
|
||||
modeDefault: 'simples',
|
||||
toolsVisibility: {
|
||||
'cev': true,
|
||||
'seletor': true,
|
||||
'equivalencias': false,
|
||||
'comparativo': false,
|
||||
'parafusos': true,
|
||||
'layout': true,
|
||||
'parafuso-vs-solda': false,
|
||||
'preaquecimento': true,
|
||||
'dureza': true,
|
||||
'charpy': true,
|
||||
'certificado': false,
|
||||
'ultrassom': false,
|
||||
'area-pintura': true,
|
||||
'consumo-tinta': true,
|
||||
'galvanizacao': false,
|
||||
'custo-pintura': true,
|
||||
'secagem': false,
|
||||
'inspecao-pintura': false,
|
||||
'orcamento': true,
|
||||
'peso-rigging': false,
|
||||
'referencia': false
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Update app state
|
||||
* @param {string} key - State key
|
||||
* @param {any} value - New value
|
||||
*/
|
||||
export function updateState(key, value) {
|
||||
appState[key] = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get state value
|
||||
* @param {string} key - State key
|
||||
* @returns {any} State value
|
||||
*/
|
||||
export function getState(key) {
|
||||
return appState[key];
|
||||
}
|
||||
|
||||
/**
|
||||
* Update user preferences
|
||||
* @param {string} key - Preference key
|
||||
* @param {any} value - New value
|
||||
*/
|
||||
export function updatePreference(key, value) {
|
||||
userPreferences[key] = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get preference value
|
||||
* @param {string} key - Preference key
|
||||
* @returns {any} Preference value
|
||||
*/
|
||||
export function getPreference(key) {
|
||||
return userPreferences[key];
|
||||
}
|
||||
|
||||
@@ -1,86 +1,86 @@
|
||||
/**
|
||||
* LocalStorage Management
|
||||
* Handles persistence of user preferences
|
||||
*/
|
||||
|
||||
import { userPreferences } from './state.js';
|
||||
|
||||
const STORAGE_KEY = 'acoCalcPreferences';
|
||||
|
||||
/**
|
||||
* Load preferences from localStorage
|
||||
* @returns {boolean} Success status
|
||||
*/
|
||||
export function loadPreferences() {
|
||||
try {
|
||||
const saved = localStorage.getItem(STORAGE_KEY);
|
||||
if (saved) {
|
||||
const parsed = JSON.parse(saved);
|
||||
Object.assign(userPreferences, parsed);
|
||||
console.log('✅ Preferências carregadas:', userPreferences);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} catch (error) {
|
||||
console.warn('⚠️ Não foi possível carregar preferências:', error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save preferences to localStorage
|
||||
* @returns {boolean} Success status
|
||||
*/
|
||||
export function savePreferences() {
|
||||
try {
|
||||
localStorage.setItem(STORAGE_KEY, JSON.stringify(userPreferences));
|
||||
console.log('✅ Preferências salvas');
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.warn('⚠️ Não foi possível salvar preferências:', error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all preferences
|
||||
* @returns {boolean} Success status
|
||||
*/
|
||||
export function clearPreferences() {
|
||||
try {
|
||||
localStorage.removeItem(STORAGE_KEY);
|
||||
console.log('✅ Preferências limpas');
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.warn('⚠️ Não foi possível limpar preferências:', error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get storage size in bytes
|
||||
* @returns {number} Size in bytes
|
||||
*/
|
||||
export function getStorageSize() {
|
||||
try {
|
||||
const data = localStorage.getItem(STORAGE_KEY);
|
||||
return data ? new Blob([data]).size : 0;
|
||||
} catch (error) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if localStorage is available
|
||||
* @returns {boolean} Availability status
|
||||
*/
|
||||
export function isStorageAvailable() {
|
||||
try {
|
||||
const test = '__storage_test__';
|
||||
localStorage.setItem(test, test);
|
||||
localStorage.removeItem(test);
|
||||
return true;
|
||||
} catch (error) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* LocalStorage Management
|
||||
* Handles persistence of user preferences
|
||||
*/
|
||||
|
||||
import { userPreferences } from './state.js';
|
||||
|
||||
const STORAGE_KEY = 'acoCalcPreferences';
|
||||
|
||||
/**
|
||||
* Load preferences from localStorage
|
||||
* @returns {boolean} Success status
|
||||
*/
|
||||
export function loadPreferences() {
|
||||
try {
|
||||
const saved = localStorage.getItem(STORAGE_KEY);
|
||||
if (saved) {
|
||||
const parsed = JSON.parse(saved);
|
||||
Object.assign(userPreferences, parsed);
|
||||
console.log('✅ Preferências carregadas:', userPreferences);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} catch (error) {
|
||||
console.warn('⚠️ Não foi possível carregar preferências:', error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save preferences to localStorage
|
||||
* @returns {boolean} Success status
|
||||
*/
|
||||
export function savePreferences() {
|
||||
try {
|
||||
localStorage.setItem(STORAGE_KEY, JSON.stringify(userPreferences));
|
||||
console.log('✅ Preferências salvas');
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.warn('⚠️ Não foi possível salvar preferências:', error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all preferences
|
||||
* @returns {boolean} Success status
|
||||
*/
|
||||
export function clearPreferences() {
|
||||
try {
|
||||
localStorage.removeItem(STORAGE_KEY);
|
||||
console.log('✅ Preferências limpas');
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.warn('⚠️ Não foi possível limpar preferências:', error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get storage size in bytes
|
||||
* @returns {number} Size in bytes
|
||||
*/
|
||||
export function getStorageSize() {
|
||||
try {
|
||||
const data = localStorage.getItem(STORAGE_KEY);
|
||||
return data ? new Blob([data]).size : 0;
|
||||
} catch (error) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if localStorage is available
|
||||
* @returns {boolean} Availability status
|
||||
*/
|
||||
export function isStorageAvailable() {
|
||||
try {
|
||||
const test = '__storage_test__';
|
||||
localStorage.setItem(test, test);
|
||||
localStorage.removeItem(test);
|
||||
return true;
|
||||
} catch (error) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user