← スキル一覧に戻る

client-storage
by CeamKrier
Browser-based tool to combine and format multiple files for optimal use with AI language models (ChatGPT, Claude, etc.).
⭐ 2🍴 0📅 2026年1月17日
SKILL.md
name: client-storage description: Implement client-side storage patterns using localStorage, sessionStorage, or IndexedDB. Use for persisting user preferences, caching data, handling storage quota, and migrating stored data schemas.
Client Storage
When to Use This Skill
Use when you need to:
- Persist data in the browser (preferences, cache, state)
- Handle storage quota limits and errors
- Migrate data between schema versions
- Choose between localStorage, sessionStorage, or IndexedDB
Storage Selection Guide
| Storage | Capacity | Persistence | Use Case |
|---|---|---|---|
| localStorage | ~5-10MB | Permanent | User preferences, config |
| sessionStorage | ~5-10MB | Tab session | Temporary state |
| IndexedDB | GB+ | Permanent | Large datasets, files |
Implementation Patterns
1. Basic localStorage with Error Handling
function getItem<T>(key: string, defaultValue: T): T {
try {
const stored = localStorage.getItem(key);
return stored ? JSON.parse(stored) : defaultValue;
} catch {
return defaultValue;
}
}
function setItem<T>(key: string, value: T): boolean {
try {
localStorage.setItem(key, JSON.stringify(value));
return true;
} catch (error) {
if (error instanceof DOMException && error.name === 'QuotaExceededError') {
console.warn('Storage quota exceeded');
}
return false;
}
}
2. Versioned Config Pattern
type Config = {
version: number;
// ... config fields
};
const CURRENT_VERSION = 2;
function migrateConfig(old: unknown): Config {
const config = old as Record<string, unknown>;
// v1 -> v2 migration
if (!config.version || config.version < 2) {
return {
version: CURRENT_VERSION,
// migrate fields...
};
}
return config as Config;
}
function loadConfig(): Config {
const stored = getItem('config', null);
if (!stored) return DEFAULT_CONFIG;
if (stored.version !== CURRENT_VERSION) {
const migrated = migrateConfig(stored);
setItem('config', migrated);
return migrated;
}
return stored;
}
3. React Hook Pattern
function useLocalStorage<T>(key: string, defaultValue: T) {
const [value, setValue] = useState<T>(() =>
getItem(key, defaultValue)
);
const setStoredValue = useCallback((newValue: T | ((prev: T) => T)) => {
setValue(prev => {
const resolved = newValue instanceof Function
? newValue(prev)
: newValue;
setItem(key, resolved);
return resolved;
});
}, [key]);
return [value, setStoredValue] as const;
}
4. IndexedDB for Large Data
async function openDB(name: string, version: number): Promise<IDBDatabase> {
return new Promise((resolve, reject) => {
const request = indexedDB.open(name, version);
request.onerror = () => reject(request.error);
request.onsuccess = () => resolve(request.result);
request.onupgradeneeded = (event) => {
const db = request.result;
// Create object stores during upgrade
if (!db.objectStoreNames.contains('files')) {
db.createObjectStore('files', { keyPath: 'id' });
}
};
});
}
Quota Handling
async function checkStorageQuota(): Promise<{used: number; quota: number}> {
if ('storage' in navigator && 'estimate' in navigator.storage) {
const estimate = await navigator.storage.estimate();
return {
used: estimate.usage || 0,
quota: estimate.quota || 0
};
}
return { used: 0, quota: 0 };
}
Best Practices
- Always wrap in try-catch - Storage can fail (private mode, quota)
- Version your schemas - Enable smooth migrations
- Use type guards - Validate data structure on load
- Handle quota errors - Inform user, cleanup old data
- Sync across tabs - Use
storageevent for multi-tab apps
スコア
総合スコア
65/100
リポジトリの品質指標に基づく評価
✓SKILL.md
SKILL.mdファイルが含まれている
+20
○LICENSE
ライセンスが設定されている
0/10
✓説明文
100文字以上の説明がある
+10
○人気
GitHub Stars 100以上
0/15
○最近の活動
3ヶ月以内に更新がある
0/10
○フォーク
10回以上フォークされている
0/5
✓Issue管理
オープンIssueが50未満
+5
✓言語
プログラミング言語が設定されている
+5
✓タグ
1つ以上のタグが設定されている
+5
レビュー
💬
レビュー機能は近日公開予定です

