[chrome拡張機能]求む!storageのいい感じのラップ方法
chrome拡張機能でstorageをラップしたい
要約
chrome拡張機能を開発する時って、コールバックばっかりでしんどいですよね。特にstorageみたいな使う頻度が高くなりそうなapiは、できればpromise化して使いやすくしたいです。(拡張機能でにそこまでやる必要ある?みたいな話もありますが)
この記事ではstorageをクラスとしてまとめてみたのですが、もうちょっといい感じにならないものかと思い記事にしてみた次第です。ご意見いただけたらうれしいです。
勿論、どう使うかによっても色々考え方変わると思いますが、一旦ある程度汎用的に使えるものを想定して下記クラスを作成しています。
前提情報
・storageのデータ保存方法は所謂key-value方式。
・一個のオブジェクトへ保存していくイメージ。
※他にも色々制約などがありますが下記リンクにて
raz的な実装イメージ
storageのinterface・抽象クラス
export type StorageType = 'local' | 'sync';
export interface StorageInterFace<T> {
readonly key: string;
initializeData(): T;
}
export interface StorageData {
isInitialized: boolean;
}
export abstract class Storage<T extends StorageData> implements StorageInterFace<T> {
private storage: chrome.storage.LocalStorageArea | chrome.storage.SyncStorageArea;
readonly key: string;
protected constructor(key: string, saveType?: StorageType) {
this.key = key;
this.storage = saveType === 'sync' ? chrome.storage.sync : chrome.storage.local;
}
save = async (data: T) => {
// keyのつけ外しをこのクラス内でやってあげることで、データの扱いが無茶苦茶やり易いはず。
const saveObject = {
[this.key]: data,
};
return await new Promise((resolve, reject) => {
this.storage.set(saveObject, () => {
if (chrome.runtime.lastError) {
reject(chrome.runtime.lastError);
}
});
});
};
load = async (): Promise<T> => {
return await new Promise((resolve, reject) => {
this.storage.get(this.key, async (result) => {
if (chrome.runtime.lastError) {
reject(chrome.runtime.lastError);
}
// 普通のSaasとかと違ってDB(storage)の環境設定とかがあらかじめできるわけではないので、
// 初回データアクセス時はundifinedの判定と初期データの作成をしてあげる必要があります。
const data = result[this.key] as T;
if (!data?.isInitialized) {
const initData = this.initializeData();
await this.save(initData);
resolve(initData);
}
resolve(result[this.key] as T);
});
});
};
abstract initializeData(): T;
}
実装クラス(一例)
import { StorageData, StorageType, Storage } from './Storage';
interface ConfigData extends StorageData {
storageType: StorageType;
}
const config_key = 'custum_tabGroup_config';
export class ConfigStorage extends Storage<ConfigData> {
// initをstatic化しているのは他のkeyの値を参照したいケースがあると思っているため。
// (例えばメインの大きめなデータはlocalに保存するかどうか設定として持っておくかどうかを選べる様にするとかがある想定です。)
static init = () => new ConfigStorage(config_key, 'sync');
initializeData = (): ConfigData => ({ isInitialized: true, storageType: 'sync' });
}
宣伝
本当に大した機能じゃないですが、拡張機能リリースしたのでよかったらみてみてください。
githubもpublicにしてみました。
https://github.com/R-Az/custum_tabGroup
https://chrome.google.com/webstore/detail/tabgroupcustoms/aiidfmkcfamdjancnfkppnbhakahcndm?hl=ja
Author And Source
この問題について([chrome拡張機能]求む!storageのいい感じのラップ方法), 我々は、より多くの情報をここで見つけました https://qiita.com/R-Az/items/7f4c1e13363e2c3e8910著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .