Skip to content

SvelteのStoreをクラスベースで実装する

Published:

はじめに

tauriの設定読み込みを部分を実装する際に、storeを実装するものの、クラスベースで実装する方法がわからなかったので調査した。

全体の実装

全体のコードは以下の通り。

import { readTextFile, writeTextFile, BaseDirectory } from '@tauri-apps/api/fs';
import { writable, get, type Invalidator, type Subscriber } from 'svelte/store';

const FILENAME = 'config.json';
const defaultSettings = {
    // 適当な初期値
};

class SettingsStore {
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    private store;

    constructor() {
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        this.store = writable<Record<string, any>>(defaultSettings);
        this.load();
    }

    get settings() {
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        return get<Record<string, any>>(this.store);
    }

    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    set(key: string, value: any): any {
        this.store.update((settings) => {
            settings[key] = value;
            return settings;
        });
        this.save();
        return value;
    }

    subscribe(
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        run: Subscriber<Record<string, any>>,
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        invalidate?: Invalidator<Record<string, any>> | undefined
    ) {
        return this.store.subscribe(run, invalidate);
    }

    private async load() {
        try {
            const config = await readTextFile(FILENAME, { dir: BaseDirectory.AppConfig });
            this.store.set(JSON.parse(config));
        } catch (e) {
            console.error(e);
            this.store.set(defaultSettings);
            this.save();
        }
    }

    private save() {
        writeTextFile(FILENAME, JSON.stringify(get(this.store)), { dir: BaseDirectory.AppConfig });
    }
}

export const settings = new SettingsStore();

要所の解説

    constructor() {
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        this.store = writable<Record<string, any>>(defaultSettings);
        this.load();
    }
    get settings() {
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        return get<Record<string, any>>(this.store);
    }

クラスを呼び出す

svelteのコンポーネントでstoreを使用する際は、以下のように呼び出す。

<script>
  import { settings } from './store';
  console.log($settings.key);

  // 設定から新しくstoreを作成
  $: newSettings = $settings.key;
</script>

まとめ

以上、SvelteのStoreをクラスベースで実装する方法を紹介した。storeについて理解度が深まり、コードの再利用性が向上し、保守性が高まった。

書籍紹介

つくって、壊して、直して学ぶ Kubernetes入門

つくって、壊して、直して学ぶ Kubernetes入門