IndexedDB patterns, storage quotas, and offline data persistence for SPC files and user data.
Use this skill when implementing file storage, playlists, preferences, or any persistent client-side data.
IndexedDB is the primary storage mechanism for SPC Player. It stores:
const DB_NAME = 'spc-player';
const DB_VERSION = 1;
// Object stores:
// 'files' — key: auto-increment id, indexes: [hash, name, game, artist]
// 'playlists' — key: auto-increment id, indexes: [name]
// 'settings' — key: string (setting name), value: any
Use a lightweight wrapper like idb (by Jake Archibald) for a Promise-based API:
import { openDB } from 'idb';
const db = await openDB(DB_NAME, DB_VERSION, {
upgrade(db) {
const fileStore = db.createObjectStore('files', {
keyPath: 'id',
autoIncrement: true,
});
fileStore.createIndex('hash', 'hash', { unique: true });
fileStore.createIndex('game', 'game');
db.createObjectStore('settings');
},
});
// Store a file
await db.put('files', {
hash,
name,
data: arrayBuffer,
game,
artist,
addedAt: Date.now(),
});
// Get by ID
const file = await db.get('files', id);
// Query by game
const files = await db.getAllFromIndex('files', 'game', 'Chrono Trigger');
const { usage, quota } = await navigator.storage.estimate();await navigator.storage.persist();QuotaExceededError when writing.upgrade callback.