Folia IndexedDB Schema: Inside KineticPlayerDB’s Six Object Stores
Folia persists runtime data in a version 5 IndexedDB database named KineticPlayerDB that contains six specialized object stores—session, api_cache, user_cache, media_cache, metadata_cache, and local_music—each optimized for specific data types ranging from transient session state to binary media blobs and locally imported tracks.
The open-source Folia project (chthollyphile/folia-major) implements a robust client-side storage layer using IndexedDB to manage everything from temporary UI variables to persistent local music libraries. The complete schema definition and migration logic reside in src/services/db.ts, where the database is initialized with automatic versioning that handles seamless upgrades from legacy schema versions.
Database Configuration and Versioning
The IndexedDB schema is anchored by constants defined at the top of src/services/db.ts (lines 7–15):
const DB_NAME = 'KineticPlayerDB';
const DB_VERSION = 5;
const STORE_NAME = 'session';
const CACHE_STORE = 'api_cache';
const USER_CACHE_STORE = 'user_cache';
const MEDIA_CACHE_STORE = 'media_cache';
const METADATA_CACHE_STORE = 'metadata_cache';
const LOCAL_MUSIC_STORE = 'local_music';
The database opens with an onupgradeneeded handler that branches on oldVersion to create stores incrementally. This ensures that users migrating from earlier installs receive the full schema without data loss.
The Six Object Stores
Folia separates concerns across six distinct object stores, each with specific key paths and data interfaces.
session
The session store holds transient runtime information such as the current audio file, active lyrics, theme preferences, and cached AI backgrounds. Unlike other stores, it uses no explicit key path; instead, keys are supplied explicitly during put operations.
- Key path: None (explicit key per entry)
- Interface:
SessionData - Fields:
audioFile?,fileName?,lyricId?,lyrics?,theme?,cachedAiBg?,coverUrl?,timestamp?
api_cache
The api_cache store maintains backward-compatible caching for legacy keys like last_song, last_queue, and last_theme. It serves as a general-purpose key-value cache with a standardized shape.
- Key path:
key - Interface:
CacheData - Shape:
{ key: string, data: any, timestamp: number }
user_cache
Introduced in schema versions below 3, the user_cache store migrates user-related objects from the legacy api_cache store. It holds profiles, playlists, liked songs, and cloud playlist data using the same CacheData interface.
- Key path:
key - Interface:
CacheData - Migration: Existing user data moves from
api_cachetouser_cacheduring upgrades
media_cache
The media_cache store manages binary blobs for media assets, including audio files (prefixed with audio_*) and cover images (prefixed with cover_*). These are stored directly as blobs within the CacheData wrapper.
- Key path:
key - Content: Binary audio and image data
- Naming convention:
audio_*for tracks,cover_*for artwork
metadata_cache
The metadata_cache store indexes lyric files, theme definitions, and playlist details. Keys follow strict prefixes to distinguish entity types: lyric_ for lyrics, theme_ for themes, playlist_tracks_ for track listings, and playlist_detail_ for playlist metadata.
- Key path:
key - Interface:
CacheData - Key prefixes:
lyric_,theme_,playlist_tracks_,playlist_detail_
local_music
The local_music store is the only schema element using a custom key path. It persists locally imported songs with a structured LocalSong interface defined in src/types.ts. Each entry carries its own unique identifier, making it suitable for primary key indexing.
- Key path:
id - Interface:
LocalSong - Created: Version 4 and above (lines 103–107 in
src/services/db.ts)
Schema Migration Logic
The onupgradeneeded handler in openDB implements incremental migration:
- Base stores: Ensures
sessionandapi_cacheexist with{ keyPath: 'key' }for the cache store. - Version < 3: Adds
user_cache,media_cache, andmetadata_cacheif upgrading from legacy installs. - Version 4+: Creates
local_musicwith{ keyPath: 'id' }.
During upgrades from pre-version 3, the code explicitly migrates legacy user data from api_cache to user_cache, ensuring continuity without duplicate entries.
Working with the Schema
The following patterns demonstrate how to interact with the IndexedDB schema using the helper functions exported from src/services/db.ts:
import {
openDB,
saveSessionData,
getSessionData,
saveLocalSong,
getLocalSongs,
saveToCache,
getFromCache,
} from '@/services/db';
// Open the database (typically handled automatically by helpers)
const db = await openDB();
// Store transient session data
await saveSessionData('coverUrl', 'https://example.com/cover.png');
// Retrieve the complete session object
const session = await getSessionData();
// Cache an API response in the user_cache store
await saveToCache('last_song', { title: 'Demo Track', artist: 'Example Artist' });
// Read cached values with type safety
const lastSong = await getFromCache<{title: string; artist: string}>('last_song');
// Persist a local song to the local_music store
await saveLocalSong({
id: 'song-123',
title: 'My Track',
// ... other LocalSong fields
});
// Fetch all locally stored songs
const localSongs = await getLocalSongs();
Summary
- Folia IndexedDB schema centers on a single database named
KineticPlayerDBat version 5, defined insrc/services/db.ts. - Six object stores handle distinct responsibilities:
sessionfor transient state,api_cachefor legacy compatibility,user_cachefor user objects,media_cachefor binary blobs,metadata_cachefor lyrics and themes, andlocal_musicfor imported tracks. - Versioned migrations automatically create stores and migrate legacy data when users upgrade the application.
- Consistent interfaces: Five stores use the
CacheDatashape with akeyprimary key, whilelocal_musicuses theLocalSonginterface with anidkey path. - Type definitions for all data shapes reside in
src/types.ts.
Frequently Asked Questions
What is the name and current version of Folia's IndexedDB database?
The database is named KineticPlayerDB and currently runs at version 5. These constants are hardcoded in src/services/db.ts and drive the onupgradeneeded migration logic.
How does Folia handle schema upgrades when the stored version is outdated?
Folia implements an onupgradeneeded handler that checks oldVersion and incrementally creates missing stores. For versions below 3, it adds user_cache, media_cache, and metadata_cache. For version 4 and above, it creates the local_music store. Legacy user data automatically migrates from api_cache to user_cache during these upgrades.
Why does the local_music store use a different key path than the other stores?
The local_music store uses { keyPath: 'id' } because it stores LocalSong objects that already contain unique identifiers. All other stores use a generic { keyPath: 'key' } configuration with a CacheData wrapper, allowing flexible string-based lookups for cached blobs and metadata.
Where are binary audio files and cover images stored in the Folia IndexedDB schema?
Binary media assets reside in the media_cache store. Audio files are stored with keys prefixed by audio_*, while cover images use the cover_* prefix. Both are wrapped in the standard CacheData interface and stored as Blob objects.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →