JavaScript IndexedDBの使い方 独自のファイルキャッシュ作成

ブラウザのファイルキャッシュはほとんど制御できませんが、IndexedDBを使用すれば独自のファイルキャッシュシステム等が作成可能になります。
mdn web docsを参考にソースコードを作成しています。

IndexedDB

Key(string number ほか)を使ってJavaScriptのオブジェクトを格納取得できるオブジェクト指向データベースです。詳しくは検索とかで。

とりあえずファイルキャッシュのようなもの

そのままだと使いにくいのでラップクラス(IddDataBase)を作りました。

    // とりあえずIndexedDataBaseでファイルキャッシュ
    let objStore = "fileCache";
    let version = 2;
    let nameDB = "DataBaseName0123";
    let idddb = await IddDataBase.openDB(nameDB, version, objStore);

    // ファイル登録 最初だけ(インストール)
    let url = "./test.dat";
    let file = await (await fetch("./test.dat")).arrayBuffer();
    await idddb.putObj(objStore, url, file);

    // ファイル(キャッシュ)取得
    let obj = await idddb.getObj(objStore, url);
    console.log(obj)
    // なかったらfetchで取得とか

    // ファイル(キャッシュ)削除
    await idddb.deleteObj(objStore, url);

    idddb.close();

    // DB削除(アンインストール)
    await IddDataBase.deleteDatabase(nameDB);

ラップクラス(IddDataBase)

// IndexedDataBaseを使ってみる
export class IddDataBase{
    db : IDBDatabase;
    private constructor(db : IDBDatabase){
        this.db = db;
    }

    static async deleteDatabase(name : string){
        let del = indexedDB.deleteDatabase(name);
        await new Promise<void>((rs, rj)=>{
            del.onsuccess = ()=>{
                console.log("db delete");
                rs()
            };
            del.onerror = (event)=>{
                console.log("db delete error");
                rj(event);
            };
        })
    }

    static async openDB(name : string, version : number, objStore : string) : Promise<IddDataBase>{
        let open = indexedDB.open(name, version);
        let db = await new Promise<IDBDatabase>((rs,rj)=>{

            // 新規orアップグレード
            open.onupgradeneeded = (event : IDBVersionChangeEvent)=>{
                console.log("db upgrade", event);
                let db = open.result;

                if(event.oldVersion > 0 && event.oldVersion != event.newVersion){
                    // アップグレード処理とか
                }
               
                // オブジェクトストアを作成
                db.createObjectStore(objStore);
            };

            open.onsuccess = ()=>{
                let db = open.result;
                console.log("db open success ver"+db.version);
                rs(db);
            };

            open.onerror = (event)=>{
                console.log("db open error");
                rj(event);
            };

        }).catch(e=>{
            throw e;
        });
        return new IddDataBase(db);
    }

    close(){
        this.db.close();
    }

    async getObj(storeName : string, key : IDBValidKey) {
        let trans = this.db.transaction(storeName, "readonly");
        var store = trans.objectStore(storeName);
        let get = store.get(key);

        // トランザクション完了待ち
        await new Promise<any>((rs, rj)=>{
            get.onerror = rj;
            trans.oncomplete = rs;
            trans.onerror = rj;
            trans.onabort = rj;
        });

        return get.result;
    }

    async putObj(storeName:string, key : IDBValidKey, obj : any ){
        let trans = this.db.transaction(storeName, "readwrite");
        var store = trans.objectStore(storeName);
        let put = store.put(obj, key);

        await new Promise<any>((rs, rj)=>{
            put.onerror = rj;
            trans.oncomplete = rs;
            trans.onerror = rj;
            trans.onabort = rj;
        });
    }
   
    async deleteObj(storeName : string, key : IDBValidKey){
        let trans = this.db.transaction(storeName, "readwrite");
        var store = trans.objectStore(storeName);
        let del = store.delete(key);

        await new Promise<any>((rs,rj)=>{
            del.onerror = rj;
            trans.oncomplete = rs;
            trans.onerror = rj;
            trans.onabort = rj;
        });
    }
}

この記事が役に立ったという方は、サポートお願いします。今後の製作の励みになります。