Svelte Stores x Dexie 2.0

Svelte Stores x Dexie 2.0

Мой первый пост был посвящен подключению svelte store к indexedDB. Этот пост будет обновлением на ту же тему. Продолжайте читать, если вам нужен совершенно другой подход, более практичный в большинстве случаев!

Чего я хочу добиться

Я хочу сохранять данные в indexedDB и использовать их в своем приложении.

Проблема

Поскольку idexedDB работает асинхронно, в большинстве случаев страница загружается раньше данных, что приводит к некрасивому мерцанию при обновлении элементов из-за реактивной природы svelte. Поэтому, по возможности, данные должны загружаться из хранилища, а не из самой indexedDB. Очевидно, что данные должны быть загружены один раз при начальной загрузке страницы — но в SPA это все!

Решение

Маленькое хранилище со специальной функцией, которая получает данные из индексированной базы данных. В принципе, это все, но есть несколько важных тонкостей, которые я объясню через минуту.

Установите Dexie

Для того чтобы использовать это, вам нужно установить Dexie.js:

npm install dexie

Создайте db.js

Это очень минималистичная установка для вашей indexedDB, которая находится в папке lib:

import Dexie from 'dexie';

export const db = new Dexie("user");

db.version(1).stores({
  user: "key, value"
});

Создайте stores.js

Это фактический магазин, который вы можете использовать в вашем +page.svelte. Как вы видите, в нем есть функция sync, которая получает данные из индексированной базы данных Dexie и устанавливает данные userData. Она также возвращает обещание, которое будет очень полезно через секунду.

import { writable } from "svelte/store";
import { db } from "$lib/db";

export const userData = writable([]);

userData.sync = function() {
    return new Promise (async (resolve, reject) => {
        try {
            const data = await db.progress.toArray();
            userData.set(data);

            resolve();
        } catch (error) {
            console.error(error);

            reject (error);
        }
    })
}

Как загрузить

import { userData } from "@stores"; // I am using an alias here

<script>
    function handleMount() {
        userData.sync()
    }

    onMount(handleMount);
</script>

<main>
    {#each userData as data}
        <p>{data.name}, {data.age}</p>
    {/each}
</main>

Выполняйте действия, когда данные загружены

Иногда необходимо дождаться данных, чтобы вызвать функцию. Это больше не проблема, поскольку вы можете просто использовать .then после функции sync-Function.

import { userData } from "@stores"; // I am using an alias here

<script>
    function handleMount() {
        userData.sync()
        .then(() => {
            // do stuff!
        })
    }

    onMount(handleMount);
</script>

<main>
    {#each userData as data}
        <p>{data.name}, {data.age}</p>
    {/each}
</main>

Как сохранить

Чтобы сохранить данные в indexedDB, просто используйте Dexie API, а затем обновите хранилище:

    function saveData() {
        db.user.put({ name, inputValue });
        userData.sync()
    }

Мне очень нравится этот рабочий процесс, поскольку он дает мне больше контроля, чем предыдущее решение, но при этом остается очень, очень простым!

Ваше здоровье,