quarrant / mobx-persist-store

Persist and rehydrate observable properties in mobx store.
270 stars 14 forks source link

Doesnt work with `chrome.storage.local.get` API #20

Closed deadcoder0904 closed 3 years ago

deadcoder0904 commented 3 years ago

I made a new little Chrome Extension to see if this library works with Chrome extension & it does work with LocalStorage.

However, it doesn't work with chrome.storage.local.get API as the return type of read in StorageAdapter is:

read: (name: string) => Promise<string | undefined>

While chrome.storage.local.get returns:

read: (name: string) => Promise<{ [key: string]: any }>

I even tried resolving the promise by using JSON.stringify but then it gets issue #15 where it always starts from the initial value 0 but perfectly logs stored value in the console.

So I think the read function should use the type T rather than string.

Also, lmk if there's any other solution to this problem.

Let me know if you would like to test the Chrome Extension so I can create a Github repo :)

deadcoder0904 commented 3 years ago

This is where the problem is:

https://github.com/quarrant/mobx-persist-store/blob/c99f4e09050257fece871d7f01952250671ae9a8/src/types.ts#L13-L16

And they should be changed to:

export type StorageAdapterOptions = {
  write: (name: string, value: T) => Promise<Error | undefined>;
  read: (name: T) => Promise<T | undefined>;
};

I'm a TS noob so do double-check :)

quarrant commented 3 years ago

No, types in mobx-persist-store/src/types.ts is correct

quarrant commented 3 years ago

@deadcoder0904 If you want to use chrome.storage, then you should adapt it for StorageAdapter, and not edit the typing

deadcoder0904 commented 3 years ago

Well, here's my code:

import {
    persistence,
    useClear,
    useDisposers,
    isSynchronized,
    StorageAdapter,
} from 'mobx-persist-store'

import { CounterStore } from './store'

const read = (name: string): Promise<{ [key: string]: any }> =>
    new Promise((resolve) => {
        // const data = localStorage.getItem(name) || '{}'
        console.log(name)
        chrome.storage.local.get(name, function (data) {
            console.log('got data: ', data)
            resolve(data)
        })
    })

const write = (name: string, content: string): Promise<Error | undefined> =>
    new Promise((resolve) => {
        console.log('write data: ', name, content)
        chrome.storage.local.set({ [name]: content }, function () {
            // localStorage.setItem(name, content)
            resolve(undefined)
        })
    })

export const PersistState = persistence({
    name: 'CounterStore',
    properties: ['counter'],
    adapter: new StorageAdapter({ read, write }),
    reactionOptions: {
        // optional
        delay: 2000,
    },
})(new CounterStore())

If I change read & write function, then it shows red-squiggly lines under read & write in StorageAdapter.

Currently with the above code, it shows red-squiggly lines under read with the following error:

Type '(name: string) => Promise<{ [key: string]: any; }>' is not assignable to type '(name: string) => Promise<string | undefined>'. Type 'Promise<{ [key: string]: any; }>' is not assignable to type 'Promise<string | undefined>'. Type '{ [key: string]: any; }' is not assignable to type 'string'.

Even though when I control click StorageAdapter, it opens up StorageAdapater.d.ts which shows correct types:

import { StorageAdapterOptions } from './types';
export declare class StorageAdapter {
    private write;
    private read;
    constructor(options: StorageAdapterOptions);
    writeInStorage<T>(name: string, content: T): Promise<void | Error>;
    readFromStorage<T>(name: string): Promise<T | undefined>;
}

I don't see any issue here. Do you?

quarrant commented 3 years ago

Read the docs of chrome.storage. Function get returns an object where key as name of storage. Try it:

chrome.storage.get(name, (data) => resolve(data[name]))
deadcoder0904 commented 3 years ago

As always, it worked 🎉

Would appreciate if you can take a look at https://github.com/quarrant/mobx-persist-store/issues/14#issuecomment-779150211 :)