rusttaurizustand

Tauri tauri-apps/plugin-store + zustand


I'm trying to create a custom storage in zustand for tauri-apps/plugin-store. When trying to change the state, I get an error in the console

[zustand persist middleware] Unable to update item 'storage', the given storage is currently unavailable.

Who has encountered this or can help?

Here is my store and storage code.

import {create} from 'zustand'
import {persist, createJSONStorage, StateStorage} from 'zustand/middleware'
import {Store} from '@tauri-apps/plugin-store';
export const store = new Store('globalStore.bin');

interface MyState {
    bears: number
    addABear: () => void
}

export const useBearStore = create<MyState>()(
    persist((set, get) => ({
            bears: 0,
            addABear: () => set({bears: get().bears + 1}),
        }),
        {
            name: 'storage', // name of item in the storage (must be unique)
            storage: createJSONStorage(() => storage), // (optional) by default the 'localStorage' is used
        },
    ),
)

const storage: StateStorage = {
    getItem: async (name: string): Promise<string | null> => {
        console.log(name)
        return (await store.get(name)) || null
    },
    setItem: async (name: string, value: string): Promise<void> => {
        console.log(name, value)
        await store.set(name, value)
    },
    removeItem: async (name: string): Promise<void> => {
        console.log(name)
        await store.delete(name)
    },
}

Solution

  • Here's a working source code with zustand.

    All you had to do is to move storage above useBearStore. Hopefully zustand maintainers see this and fix the issue.

    import {create} from 'zustand'
    import {persist, createJSONStorage, StateStorage} from 'zustand/middleware'
    import {Store} from '@tauri-apps/plugin-store';
    export const store = new Store('globalStore.bin');
    
    interface MyState {
        bears: number
        addABear: () => void
    }
    
    const storage: StateStorage = {
        getItem: async (name: string): Promise<string | null> => {
            console.log(name)
            return (await store.get(name)) || null
        },
        setItem: async (name: string, value: string): Promise<void> => {
            console.log(name, value)
            await store.set(name, value)
        },
        removeItem: async (name: string): Promise<void> => {
            console.log(name)
            await store.delete(name)
        },
    }
    
    export const useBearStore = create<MyState>()(
        persist((set, get) => ({
                bears: 0,
                addABear: () => set({bears: get().bears + 1}),
            }),
            {
                name: 'storage', // name of item in the storage (must be unique)
                storage: createJSONStorage(() => storage), // (optional) by default the 'localStorage' is used
            },
        ),
    )